ANTLR4语法开始出现';和';和';或';以变量名

ANTLR4语法开始出现';和';和';或';以变量名,antlr4,Antlr4,请帮助我学习ANTLR4语法 样本“formel”: (Arbejde.ArbejderIKommuneNr=860)和(Arbejde.ErIArbejde='J')& (Arbejde.ArbejdsTimerPrUge=40) (Ansogeren.BorIKommunen='J')和(BeregnDato)(Ansogeren.Fodselsdato; “+62Å”)

请帮助我学习ANTLR4语法

样本“formel”:

  • (Arbejde.ArbejderIKommuneNr=860)和(Arbejde.ErIArbejde='J')& (Arbejde.ArbejdsTimerPrUge=40)
  • (Ansogeren.BorIKommunen='J')和(BeregnDato)(Ansogeren.Fodselsdato; “+62Å”)
  • (平均BorI=860)
我的问题是Arb.BorI=860处理不正确。我得到这个错误:

  • 错误:在第行输入“(Arb.Bor)”处没有可行的备选方案/位置:1/6\r\n异常:Der blev udløst en undtagelse af typen'Antlr4.Runtime.noviablealException
请注意,Arb.BorI包含“or”一词。 我想我的问题是语法中的“booleanOps”覆盖了“datakildefelt”

所以…我的问题是我该如何纠正我的语法-我被卡住了,所以任何帮助都将不胜感激

我的语法:

grammar UnikFormel;

formel  :  boolExpression   # BooleanExpr
        |  expression       # Expr
        | '(' formel ')'    # Parentes;

boolExpression : ( '(' expression ')'  ) ( booleanOps '(' expression ')'  )+;

expression :  element compareOps element    # Compare;

element : datakildefelt     # DatakildeId
        | function          # Funktion
        | int               # Integer
        | decimal           # Real
        | string            # Text;

datakildefelt : datakilde '.' felt;
datakilde : identifyer;
felt : identifyer;

function : funktionsnavn ('(' funcParameters? ')')?;
funktionsnavn : identifyer;
funcParameters : funcParameter (';' funcParameter)*;
funcParameter   : element;

identifyer : LETTER+;
int : DIGIT+;
decimal :   DIGIT+ '.' DIGIT+ | '.' DIGIT+;
string : QUOTE .*?  QUOTE;

booleanOps   : (AND | OR);
compareOps   : (LT | GT | EQ | GTEQ | LTEQ);

QUOTE : '\'';
OPERATOR: '+';
DIGIT: [0-9];
LETTER: [a-åA-Å];
MUL   : '*';
DIV   : '/';
ADD   : '+';
SUB   : '-';
GT    : '>';
LT    : '<';
EQ    : '=';
GTEQ  : '>=';
LTEQ  : '<=';
AND   : '&' | 'and';
OR    : '?' | 'or';
WS    : ' '+ -> skip;
语法统一格式;
formel:boolExpression#BooleanExpr
|表达式#Expr
|"("formel")"父母,;
boolExpression:('('expression'))(booleanOps'('expression'))+;
表达式:element compareOps element#Compare;
元素:datakildefelt#DatakildeId
|功能#功能
|整数
|十进制#实数
|字符串#文本;
datakildefelt:datakilde'.'毡;
datakilde:标识符;
毛毡:识别器;
函数:funktionsnavn('('funcParameters?'))?;
funktionsnavn:识别器;
funcParameters:funcParameter(“;”funcParameter)*;
funcParameter:元素;
标识符:字母+;
整数:数字+;
十进制:数字+'.'数字+|'.'数字+;
字符串:QUOTE.*?QUOTE;
布尔运算:(和|或);
比较:(LT | GT | EQ | GTEQ | LTEQ);
引号:“\”;
运算符:'+';
数字:[0-9];
信:[a-åa-Å];
MUL:“*”;
分区:“/”;
加:“+”;
SUB:“-”;
GT:“>”;
LT:'=';

LTEQ:“先到的规则总是有优先权的。在你的情况下,你需要将
移到
字母之前。另外
GTEQ和
LTEQ
也有同样的问题,可能在其他地方

编辑


此外,您应该将
IDENTIFIER
作为词法规则,即以大写字母开头(
IDENTIFIER
IDENTIFIER
)。对于
int
decimal
string
也是如此。输入最初是一个字符流,首先只使用lexer规则处理为一个令牌流。此时,解析器规则(以小写字母开头的规则)还没有发挥作用。因此,让“BorI”作为单个实体(令牌)进行解析,您需要创建一个与标识符匹配的lexer规则。目前,它将被解析为3个标记:
字母
(B)
(或)
字母
(I)。

感谢您的帮助。出现了多个问题。阅读ANTLR4手册并使用“TestRig-gui”使我走上了正确的道路。工作语法是:

grammar UnikFormel;

formel  : '(' formel ')'    # Parentes
        | expression        # Expr
        | boolExpression    # BooleanExpr
        ;

boolExpression : '(' expression ')' ( booleanOps '(' expression ')'  )+
        | '(' formel ')' ( booleanOps '(' formel ')'  )+;

expression :  element compareOps element    # Compare;

datakildefelt : ID '.' ID;

function : ID ('(' funcParameters? ')')?;
funcParameters : funcParameter (';' funcParameter)*;
funcParameter   : element;

element : datakildefelt     # DatakildeId
        | function          # Funktion
        | INT               # Integer
        | DECIMAL           # Real
        | STRING            # Text;

booleanOps   : (AND | OR);
compareOps   : ( GTEQ | LTEQ | LT | GT | EQ |);

AND   : '&' | 'and';
OR    : '?' | 'or';
GTEQ  : '>=';
LTEQ  : '<=';
GT    : '>';
LT    : '<';
EQ    : '=';

ID : LETTER ( LETTER | DIGIT)*;
INT : DIGIT+;
DECIMAL :   DIGIT+ '.' DIGIT+ | '.' DIGIT+;
STRING : QUOTE .*?  QUOTE;
fragment QUOTE : '\'';
fragment DIGIT: [0-9];
fragment LETTER: [a-åA-Å];
WS    : [ \t\r\n]+ -> skip;
语法统一格式;
formel:“(“formel”)”父母
|表达式#Expr
|boolExpression#BooleanExpr
;
boolExpression:'('expression')'(booleanOps'('expression'))+
|“('formel')”(booleanOps“('formel'))+;
表达式:element compareOps element#Compare;
datakildefelt:ID'.'ID;
函数:ID(“('funcParameters?)”)?;
funcParameters:funcParameter(“;”funcParameter)*;
funcParameter:元素;
元素:datakildefelt#DatakildeId
|功能#功能
|整数
|十进制#实数
|字符串#文本;
布尔运算:(和|或);
比较:(GTEQ | LTEQ | LT | GT | EQ |);
及:"&|"及";;
或:“?”|“或”;
GTEQ:“>=”;
LTEQ:“”;
LT:“跳过;

如果您通过将
表达式
的两个匹配项都更改为
formel
,然后将
+
更改为
*
中的
*
来删除
formel
中的第三行,会怎么样?我不认为Arb.Borl中的
是一个问题,因为这样您在工作示例中就有了
好的。谢谢你的建议。很抱歉,但没有起到作用。我尝试在gramar和测试数据中将“or”改为“oor”和“and”和“aand”;(Arbejde.ArbejderIKommuneNr=860)oor(Arbejde.ErIArbejde=“J”)和:“&”|“aand”或“?”|“oor”;然后它就起作用了。但我需要“and”和“or”:-(谢谢你的建议。我尝试了:
和:“&”&“|”和“;或:”?“|”或“;GTEQ:”>=”;LTEQ:”;LT:“跳过;
,但它并没有改变结果。如果异常文本不是用我不懂的语言编写的,也许我可以帮助更多。谢谢你的帮助。我已经尝试翻译错误:错误:目前没有可行的替代方案输入'(Arb.Bor'在行号/位置:1/6异常:引发了类型为'Antlr4.Runtime.NoViableAltException'的Ab异常。另外,我正在运行Antlr4.Runtime.net45。我正在将基于Delphi的旧系统迁移到.net中-在旧系统中,用户可以输入计算为真或假的业务规则'formel'。我就是这个计算程序使用ANTLR实现(我已经让访问者运行了,但是我需要'datakildefelt'-我从解析器中得到它-因为我需要在需要时向访问者提供实际值(大多数'datakildefelt'指的是数据库表的字段)1.我希望我的译文是正确的,希望你能更好地理解我在做什么。