2017-04-14 178 views
0

最近我試圖將我的項目從Antlr3升級到Antlr4。但是在語法文件發生變化之後,似乎以前工作的方程式不再有效。我對Antlr4很陌生,所以無法理解我的改變是否破壞了某些東西。爲什麼從Antlr 3升級到Antlr 4後解析失敗?

這是我原來的語法文件:

​​

這裏就是我有我的變化後:

grammar equation; 
options { 

} 

tokens { 
    VARIABLE; 
    CONSTANT; 
    EXPR; 
    PAREXPR; 
    EQUATION; 
    UNARYEXPR; 
    FUNCTION; 
    BINARYOP; 
    LIST; 
} 


equationset: equation* EOF; 
equation: variable ASSIGN expression 
    ; 

parExpression 
    : LPAREN expression RPAREN 
    ; 

expression 
    : conditionalexpression 
    ; 

conditionalexpression 
    : orExpression 
    ; 

orExpression 
    : andExpression (OR andExpression)* 
    ; 

andExpression 
    : comparisonExpression (AND comparisonExpression)*; 


comparisonExpression: 
    additiveExpression ((EQ | NE | LTE | GTE | LT | GT) additiveExpression)*; 


additiveExpression 
    : multiplicativeExpression ((PLUS | MINUS) multiplicativeExpression)* 
    ; 

multiplicativeExpression 
    : unaryExpression ((TIMES | DIVIDE) unaryExpression)* 
    ; 

unaryExpression 
    : NOT unaryExpression 
    | MINUS unaryExpression 
    | exponentexpression; 

exponentexpression 
    : primary (CARET primary)*; 

primary : parExpression | constant | booleantok | variable | function; 

numeric:  INTEGER | REAL; 
constant:  STRING | numeric; 
booleantok : BOOLEAN; 
scopedidentifier 
    : (IDENTIFIER DOT)* IDENTIFIER; 
function 
    : scopedidentifier LPAREN argumentlist RPAREN; 
variable: scopedidentifier; 

argumentlist: (expression) ? (COMMA expression)*; 

WS : (' '|'\r'|'\n'|'\t')+ ->channel(HIDDEN); 

COMMENT : '/*' .* '*/' ->channel(HIDDEN); 

LINE_COMMENT : '//' ~('\n'|'\r')* '\r'? '\n' ->channel(HIDDEN); 

STRING: (('\"') ((~('\"')))* ('\"'))+; 

fragment ALPHA: 'a'..'z'|'_'; 
fragment DIGIT: '0'..'9'; 
fragment ALNUM: ALPHA|DIGIT; 

EQ : '=='; 
ASSIGN : '='; 
NE : '!=' | '<>'; 
OR : 'or' | '||'; 
AND : 'and' | '&&'; 
NOT : '!'|'not'; 
LTE : '<='; 
GTE : '>='; 
LT : '<'; 
GT : '>'; 
TIMES : '*'; 
DIVIDE : '/'; 

BOOLEAN : 'true' | 'false'; 

IDENTIFIER: ALPHA (ALNUM)* | ('[' (~(']'))+ ']') ; 

REAL: DIGIT* DOT DIGIT+ ('e' (PLUS | MINUS)? DIGIT+)?; 
INTEGER: DIGIT+; 


PLUS : '+'; 
MINUS : '-'; 
COMMA : ','; 
RPAREN : ')'; 
LPAREN : '('; 
DOT : '.'; 
CARET : '^'; 

,我試圖分析的樣本式(這是之前確定的工作)是:

[a].[b] = 1.76 * [Product_DC].[PDC_Inbound_Pallets] * if(product_dc.[PDC_DC] =="US84",1,0) 

在此先感謝。

+0

什麼是錯誤您收到? – Raven

回答

0
  • 代幣應以逗號列表,不是分號;。官方文檔中也可參見Token Section段落。
  • 由於雙引號轉義不需要ANTLR 4.7反斜槓。 STRING: (('\"') ((~('\"')))* ('\"'))+;應改寫爲STRING: ('"' ~'"'* '"')+;
  • 您錯過了用於非貪婪匹配的多行註釋令牌中的問號:'/*' .* '*/' - >'/*' .*? '*/'

因此,固定的語法如下:

grammar equation; 

options { 

} 

tokens { 
    VARIABLE, 
    CONSTANT, 
    EXPR, 
    PAREXPR, 
    EQUATION, 
    UNARYEXPR, 
    FUNCTION, 
    BINARYOP, 
    LIST 
} 


equationset: equation* EOF; 
equation: variable ASSIGN expression 
    ; 

parExpression 
    : LPAREN expression RPAREN 
    ; 

expression 
    : conditionalexpression 
    ; 

conditionalexpression 
    : orExpression 
    ; 

orExpression 
    : andExpression (OR andExpression)* 
    ; 

andExpression 
    : comparisonExpression (AND comparisonExpression)*; 


comparisonExpression: 
    additiveExpression ((EQ | NE | LTE | GTE | LT | GT) additiveExpression)*; 


additiveExpression 
    : multiplicativeExpression ((PLUS | MINUS) multiplicativeExpression)* 
    ; 

multiplicativeExpression 
    : unaryExpression ((TIMES | DIVIDE) unaryExpression)* 
    ; 

unaryExpression 
    : NOT unaryExpression 
    | MINUS unaryExpression 
    | exponentexpression; 

exponentexpression 
    : primary (CARET primary)*; 

primary : parExpression | constant | booleantok | variable | function; 

numeric:  INTEGER | REAL; 
constant:  STRING | numeric; 
booleantok : BOOLEAN; 
scopedidentifier 
    : (IDENTIFIER DOT)* IDENTIFIER; 
function 
    : scopedidentifier LPAREN argumentlist RPAREN; 
variable: scopedidentifier; 

argumentlist: (expression) ? (COMMA expression)*; 

WS : (' '|'\r'|'\n'|'\t')+ ->channel(HIDDEN); 

COMMENT : '/*' .*? '*/' -> channel(HIDDEN); 

LINE_COMMENT : '//' ~('\n'|'\r')* '\r'? '\n' ->channel(HIDDEN); 

STRING: ('"' ~'"'* '"')+; 

fragment ALPHA: 'a'..'z'|'_'; 
fragment DIGIT: '0'..'9'; 
fragment ALNUM: ALPHA|DIGIT; 

EQ : '=='; 
ASSIGN : '='; 
NE : '!=' | '<>'; 
OR : 'or' | '||'; 
AND : 'and' | '&&'; 
NOT : '!'|'not'; 
LTE : '<='; 
GTE : '>='; 
LT : '<'; 
GT : '>'; 
TIMES : '*'; 
DIVIDE : '/'; 

BOOLEAN : 'true' | 'false'; 

IDENTIFIER: ALPHA (ALNUM)* | ('[' (~(']'))+ ']') ; 

REAL: DIGIT* DOT DIGIT+ ('e' (PLUS | MINUS)? DIGIT+)?; 
INTEGER: DIGIT+; 


PLUS : '+'; 
MINUS : '-'; 
COMMA : ','; 
RPAREN : ')'; 
LPAREN : '('; 
DOT : '.'; 
CARET : '^'; 
+0

在4.7之前的字符串文字中使用時,是否真的有必要使用雙引號?我不記得曾經需要那個...... –

+0

有沒有這種需要。但ANTLR 4.7只是對它發出警告。 –