ANTLR4语法在变量名中选择“和”和“或”

时间:2015-12-09 13:14:16

标签: antlr4

请帮我解决我的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处理不正确。我收到这个错误:

  • 错误:在输入处没有可行的选择'(在亚麻/位置的Arb.Bor':1/6 \ r \ n例外:Derblevoudløstenundtagelse af typen'Antlr4.Runtime.NoViableAltException

请注意,Arb.BorI包含“或”一词。 我认为我的问题是语法中的'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;

2 个答案:

答案 0 :(得分:0)

首先出现的规则始终具有优先权。在您的情况下,您需要在AND之前移动ORLETTER。此外,GTEQLTEQ存在同样的问题,也可能是其他问题。

修改

此外,您应该identifyer 词法分析器规则,即以大写字母(IDENTIFIERIdentifier)开头。 intdecimalstring也是如此。输入最初是一个字符流,首先只使用词法分析器规则处理成一个令牌流。此时,解析器规则(以小写字母开头的规则)尚未发挥作用。因此,要使“BorI”解析为单个实体(令牌),您需要创建匹配标识符的词法分析器规则。目前它将被解析为3个令牌:LETTER(B)OR(或)LETTER(I)。

答案 1 :(得分:0)

感谢您的帮助。有很多问题。阅读ANTLR4书并使用&#34; TestRig -gui&#34;让我走上了正确的轨道。工作语法是:

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;