ANTLR4 语法在变量名中选择 'and' 和 'or'
ANTLR4 Grammar picks up 'and' and 'or' in variable names
请帮助我学习 ANTLR4 语法。
样本"formel":
- (Arbejde.ArbejderIKommuneNr=860) 和 (Arbejde.ErIArbejde = 'J') &
(Arbejde.ArbejdsTimerPrUge = 40)
- (Ansogeren.BorIKommunen = 'J') 和 (BeregnDato(Ansogeren.Fodselsdato;
'+62Å') < DagsDato)
- (Arb.BorI=860)
我的问题是 Arb.BorI=860 处理不正确。我收到此错误:
- 错误:在 linenr/position 处的输入 '(Arb.Bor' 处没有可行的替代方案:1/6 \r\nException:在输入 'Antlr4.Runtime.NoViableAltException
请注意 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;
先到先得的规则始终具有优先权。在您的情况下,您需要在 LETTER
之前移动 AND
和 OR
。 GTEQ
和 LTEQ
也存在同样的问题,也许其他地方也存在同样的问题。
编辑
此外,您应该使 identifyer
成为 词法分析器规则 ,即以大写字母开头(IDENTIFIER
或 Identifier
)。 int
、decimal
和 string
也是如此。输入最初是字符流,首先仅使用词法分析器规则处理成标记流。此时解析器规则(那些以小写字母开头的规则)还没有发挥作用。因此,要使 "BorI" 解析为单个实体(令牌),您需要创建一个匹配标识符的词法分析器规则。目前它将被解析为 3 个标记:LETTER
(B) OR
(or) LETTER
(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;
请帮助我学习 ANTLR4 语法。
样本"formel":
- (Arbejde.ArbejderIKommuneNr=860) 和 (Arbejde.ErIArbejde = 'J') & (Arbejde.ArbejdsTimerPrUge = 40)
- (Ansogeren.BorIKommunen = 'J') 和 (BeregnDato(Ansogeren.Fodselsdato; '+62Å') < DagsDato)
- (Arb.BorI=860)
我的问题是 Arb.BorI=860 处理不正确。我收到此错误:
- 错误:在 linenr/position 处的输入 '(Arb.Bor' 处没有可行的替代方案:1/6 \r\nException:在输入 'Antlr4.Runtime.NoViableAltException
请注意 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;
先到先得的规则始终具有优先权。在您的情况下,您需要在 LETTER
之前移动 AND
和 OR
。 GTEQ
和 LTEQ
也存在同样的问题,也许其他地方也存在同样的问题。
编辑
此外,您应该使 identifyer
成为 词法分析器规则 ,即以大写字母开头(IDENTIFIER
或 Identifier
)。 int
、decimal
和 string
也是如此。输入最初是字符流,首先仅使用词法分析器规则处理成标记流。此时解析器规则(那些以小写字母开头的规则)还没有发挥作用。因此,要使 "BorI" 解析为单个实体(令牌),您需要创建一个匹配标识符的词法分析器规则。目前它将被解析为 3 个标记:LETTER
(B) OR
(or) LETTER
(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;