我的语法包含以下内容:
assignment
: ID ASSIGN expr
;
expr
: MINUS expr #unaryMinusExpr
| NOT expr #notExpr
| expr MULT expr #multExpr
| expr DIV expr #divExpr
| expr PLUS expr #plusExpr
| expr MINUS expr #minusExpr
| expr LTEQ expr #lteqExpr
| expr GTEQ expr #gteqExpr
| expr LT expr #ltExpr
| expr GT expr #gtExpr
| expr NEQ expr #neqExpr
| expr EQ expr #eqExpr
| expr AND expr #andExpr
| expr OR expr #orExpr
| function #functionExpr
| atom #atomExpr
;
function
: ID OPAR (parameter (',' parameter)*)? CPAR
;
parameter
: STRING #stringParameter
| expr #exprParameter
;
atom
: OPAR expr CPAR #parExpr
| (INT | FLOAT) #numberAtom
| (TRUE | FALSE) #booleanAtom
| ID #idAtom
;
OR : '||';
AND : '&&';
EQ : '==';
NEQ : '!=';
GT : '>';
LT : '<';
GTEQ : '>=';
LTEQ : '<=';
PLUS : '+';
MINUS : '-';
MULT : '*';
DIV : '/';
NOT : '!';
OPAR : '(';
CPAR : ')';
OBRACE : '{';
CBRACE : '}';
ASSIGN : '=';
TRUE : 'true';
FALSE : 'false';
IF : 'if';
ELSE : 'else';
ID
: [a-zA-Z_] [a-zA-Z_0-9]*
;
SPACE
: [ \t\r\n] -> skip
;
问题是ID需要还能包含MINUS,PLUS等。这意味着我不知道何时只有ID(this-isandid)或ID(this)减号ID(isandid)。
我们要做的是不跳过expr中运算符周围的空格,否则跳过所有其他规则的空格。有没有办法做到这一点?即当用户真正表达一个表达式时,我们强制用户在操作符周围放置空格,而不是包含例如MINUS。
即
a-b是ID
a - b是minusExpr
a-b,a -b是错误
或是否有其他方式允许,例如减去一个ID,并能够区分ID和minusExpr之间的区别吗?
答案 0 :(得分:1)
通过修改词法分析器中的ID
规则,您可以避免在解析器规则中对空格进行有条件的考虑。允许-
出现在ID
中,前提是它不在标识符的开头或结尾。
ID
: [a-zA-Z_]
( '-'? [a-zA-Z_0-9]
)*
;
答案 1 :(得分:0)
这可以通过使用词法模式来完成。将有一个模式(或默认模式)跳过空格,另一个模式不跳过它们。