我有一个语法,一切正常,直到这一部分:
lexp
: factor ( ('+' | '-') factor)*
;
factor :('-')? IDENT;
这当然引入了歧义。例如,a-a
可以与Factor - Factor
或Factor -> - IDENT
我收到以下警告:
[18:49:39] warning(200): withoutWarningButIncomplete.g:57:31:
Decision can match input such as "'-' {IDENT, '-'}" using multiple alternatives: 1, 2
如何解决这种歧义?我只是没有看到解决方法。我可以使用某种选项吗?
这是完整的语法:
program
: includes decls (procedure)*
;
/* Check if correct! */
includes
: ('#include' STRING)*
;
decls
: (typedident ';')*
;
typedident
: ('int' | 'char') IDENT
;
procedure
: ('int' | 'char') IDENT '(' args ')' body
;
args
: typedident (',' typedident )* /* Check if correct! */
| /* epsilon */
;
body
: '{' decls stmtlist '}'
;
stmtlist
: (stmt)*;
stmt
: '{' stmtlist '}'
| 'read' '(' IDENT ')' ';'
| 'output' '(' IDENT ')' ';'
| 'print' '(' STRING ')' ';'
| 'return' (lexp)* ';'
| 'readc' '(' IDENT ')' ';'
| 'outputc' '(' IDENT ')' ';'
| IDENT '(' (IDENT ( ',' IDENT )*)? ')' ';'
| IDENT '=' lexp ';';
lexp
: term (( '+' | '-' ) term) * /*Add in | '-' to reveal the warning! !*/
;
term
: factor (('*' | '/' | '%') factor )*
;
factor : '(' lexp ')'
| ('-')? IDENT
| NUMBER;
fragment DIGIT
: ('0' .. '9')
;
IDENT : ('A' .. 'Z' | 'a' .. 'z') (( 'A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '_'))* ;
NUMBER
: ( ('-')? DIGIT+)
;
CHARACTER
: '\'' ('a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '\\n' | '\\t' | '\\\\' | '\\' | 'EOF' |'.' | ',' |':' ) '\'' /* IS THIS COMPLETE? */
;
答案 0 :(得分:2)
如评论中所述:这些规则不含糊不清:
lexp
: factor (('+' | '-') factor)*
;
factor : ('-')? IDENT;
这是模棱两可的原因:
'return' (lexp)* ';'
可以用两种不同的方式解析输入a-b
:
a-b
作为单个二进制表达式a
作为单个表达式,-b
作为一元表达式您需要更改语法。也许在多个返回值中添加逗号?像这样:
'return' (lexp (',' lexp)*)? ';'
将匹配:
return;
return a;
return a, -b;
return a-b, c+d+e, f;
...