我有一个数学表达式语法文件,就像在线教程中的那个:http: //javadude.com/articles/antlr3xtut/
但是现在我想为函数添加选项,我很难让词法分析器/解析器规则工作。我可以使用丑陋的词法分析器规则来使代码正常工作,但我想使用更干净的令牌来使解析器规则正常工作。
如果我尝试这样做,我将在输入 'Test(' 处捕获一个“第 1:9 行没有可行的替代方案”,对于像 'a*b/13.2*Test(3,2)' 这样的表达式的异常
请检查以下语法文件中的注释,看看我的确切问题是什么
grammar ExpressionOnly;
options {
language = Java;
}
@header {
package kic.engine.grammar;
}
@lexer::header {
package kic.engine.grammar;
}
// Top Rule
eval
: expression
;
term
: func
| '(' op1=expression ')'
| array
| element
;
// Sub Terms
func
// : f=FUNC // Works but this is very ugly because FUNC contains '(';
: f=IDENT '(' // <---------------------------- why does this not work: line 1:9 no viable alternative at input 'Test('
(arg=expression (',' arg=expression)*)?
')'
;
array
: '[' ele=element (',' ele=element)* ']'
;
element
: b=(K_TRUE | K_FALSE)
| NUMBER
| IDENT
| DATE
| SQ_STRING
| K_NULL
;
negation
@init{ boolean negate = false; }
: (K_NOT | '!' { negate = true;} )?
term
;
unary
@init{ boolean positive = true; }
: ('+' | '-')*
negation
;
power
: op1=unary
( '^' op2=unary
)*
;
multiply
: op1=power
( '*' op2=power
| '/' op2=power
| '%' op2=power
)*
;
add
: op1=multiply
( '+' op2=multiply
| '-' op2=multiply
)*
;
relation
: op1=add
( '=' op2=add
| '!=' op2=add
| '<' op2=add
| '<=' op2=add
| '>' op2=add
| '>=' op2=add
)*
;
expression
: op1=relation
( (K_AND | '&') op2=relation
| (K_OR | '|') op2=relation
)*
;
// Case-insensitive alpha characters
fragment A: ('a'|'A');
fragment B: ('b'|'B');
fragment C: ('c'|'C');
fragment D: ('d'|'D');
fragment E: ('e'|'E');
fragment F: ('f'|'F');
fragment G: ('g'|'G');
fragment H: ('h'|'H');
fragment I: ('i'|'I');
fragment J: ('j'|'J');
fragment K: ('k'|'K');
fragment L: ('l'|'L');
fragment M: ('m'|'M');
fragment N: ('n'|'N');
fragment O: ('o'|'O');
fragment P: ('p'|'P');
fragment Q: ('q'|'Q');
fragment R: ('r'|'R');
fragment S: ('s'|'S');
fragment T: ('t'|'T');
fragment U: ('u'|'U');
fragment V: ('v'|'V');
fragment W: ('w'|'W');
fragment X: ('x'|'X');
fragment Y: ('y'|'Y');
fragment Z: ('z'|'Z');
// Fragments
fragment DIGIT : '0' .. '9';
fragment UPPER : 'A' .. 'Z';
fragment LOWER : 'a' .. 'z';
fragment LETTER : LOWER | UPPER;
fragment WORD : LETTER | '_' | '$' | '#' | '.';
fragment ALPHANUM : WORD | DIGIT;
fragment ESCAPE[StringBuilder buf] :
'\\'
( 't' { buf.append('\t'); }
| 'n' { buf.append('\n'); }
| 'r' { buf.append('\r'); }
| '"' { buf.append('\"'); }
| '\\' { buf.append('\\'); }
)
;
// Keyowords
K_FALSE : F A L S E;
K_NULL : N U L L;
K_TRUE : T R U E;
K_AND : A N D;
K_NOT : N O T;
K_OR : O R;
// Tokens;
FUNC : LETTER+ '(';
IDENT : LETTER ALPHANUM*;
ARRAY_INDEX : IDENT '[';
DQ_STRING
@init { final StringBuilder buf = new StringBuilder(); }
: '"'
( ESCAPE[buf]
| i = ~('\\' | '"') { buf.appendCodePoint(i); }
)*
{ setText(buf.toString()); }
;
NUMBER: DIGIT+ ('.' DIGIT+)? (('e'|'E')('+'|'-')? DIGIT+)?;
DATE: '\'' DIGIT DIGIT DIGIT DIGIT '-' DIGIT DIGIT '-' DIGIT DIGIT (' ' DIGIT DIGIT ':' DIGIT DIGIT ':' DIGIT DIGIT ('.' DIGIT+)?)? '\'';
SQ_STRING : '\'' .* '\'';
// hidden tokens
WS : (' ' | '\t' | '\r' | '\n')+ {$channel=HIDDEN;};
COMMENTS : '/*' .* '*/' {$channel=HIDDEN;};
有什么想法可以让函数规则与 IDENT 令牌一起使用吗?