我拥有的解析器代码:
funcall: ID LB exp? RB ;
exp: funcall | INTLIT ;
然后我的作业要求我需要为“funcall”这样做:
调用表达式是一个函数调用,它以标识符后跟“(”和“)”开头。可以在“(”和“)”之间出现可逗号分隔的逗号分隔表达式作为参数列表。
对于“exp”,它必须遵循Precedence和Associativity:
所以我试着写这样的代码来满足要求(我不太确定“funcall”之后文字的顺序,因为它没有在赋值中提到):
funcall: ID LB (exp (COMMA exp)*)? RB ;
exp
: LB exp RB
| LSB exp RSB
| <assoc=right> (SUB | NOT) exp
| exp op = (DIV | MUL | MODUL) exp
| exp op = (ADD | SUB) exp
| exp op = (LT | LTOE | GT | GTOE) exp
| exp op = (EQUAL | NOEQUAL) exp
| exp AND exp
| exp OR exp
| <assoc=right> exp ASSIGN exp
| funcall
| (INTLIT | FLOATLIT)
| (TRUE | FALSE)
| ID
| STRINGLIT ;
但后来我得到了这样的错误,这使我无法使用带有“(COMMA exp)”或“exp”本身的符号*:
这是ASTGeneration类的代码,我收到错误:
覆盖def visitFuncall(ctx:FuncallContext)= CallExpr(ctx.ID.getText,if(ctx.exp == null)List()else List(visit(ctx.exp).asInstanceOf [Expr]))
这是我的词法分析代码:
LB: '(' ;
RB: ')' ;
LP: '{' ;
RP: '}' ;
SEMI: ';' ;
LSB: '[' ;
RSB: ']' ;
COMMA: ',' ;
ADD: '+' ;
SUB: '-' ;
MUL: '*' ;
DIV: '/' ;
OR: '||' ;
AND: '&&' ;
NOT: '!' ;
NOEQUAL: '!=' ;
EQUAL: '==' ;
MODUL: '%' ;
ASSIGN: '=' ;
LT: '<' ;
LTOE: '<=' ;
GT: '>' ;
GTOE: '>=' ;
TRUE: 'true' ;
FALSE: 'false' ;
INTLIT: [0-9]+ ;
FLOATLIT: INTLIT DOT INTLIT ;
fragment DOT: '.' ;
ID: [_a-zA-Z] [_a-zA-Z0-9]* ;
STRINGLIT: '"' ('\\' [bfrnt'"\\] | ~[\b\f\r\n\t'"\\])*; '"' ;
WS : [ \t\r\n]+ -> skip ;
任何人都可以告诉我我的解析器代码有什么问题(现在我想知道我的“exp”可能导致“funcall”中的错误)以及我应该以哪种方式修复它。在此先感谢!!
答案 0 :(得分:0)
检查生成的代码。由于expr
规则中有多个funcall
,因此funcall上下文类中的expr
成员不是单个节点,而是一个节点(上下文)列表,其中填充了{{1}在解析过程中解析上下文。