[英]LL1 grammar for arithmetic expressions and assignments
我想为算术方程式和变量赋值设计一个LL1语法。 我从这种语法开始:
我对算术表达式有一个明确的语法:
E → T E’
E’ → | + E
T → id T’
T’ → | * T
但是,我不确定如何将变量分配合并到E生产中。
我以前的尝试是:
stmt -> assignment SEMI | RETURN stmt_prime
| LBRACE stmt_list RBRACE
| IF LPAREN assignment RPAREN stmt stmt_prime_prime
| FOR LPAREN assignment SEMI assignment SEMI assignment RPAREN stmt |
stmt_prime -> SEMI | -> assignment SEMI
stmt_prime_prime -> NOELSE
| ELSE stmt
assignment -> ID typ ASSIGN expr | expr
expr -> TE*
E* -> + TE* | -TE* | epsilon
T -> FT*
T* -> * FT* | / FT* | epsilon
F -> (E) | int_literal | TRUE | FALSE
assignment -> ID ASSIGN expr | expr
(我忽略了typ
部分,因为我认为它是偶然到达的)
这里的问题是ID ASSIGN expr
和expr
都可以以ID
开头(或者,如果T
包含ID
作为选项(我认为是故意的话),则至少可以这样),所以这不是LL(1)。 不过它是LL(2),因此,如果您对此感到满意,则可以在解析器的if
条件中添加andalso next_token = ASSIGN
并完成此操作。
如果确实需要将其设为LL(1),恐怕必须调整解析器允许的语言(也就是说,没有与您当前语言完全相同的LL(1)语法)语法)。 一种简单的解决方法是在分配之前简单地添加一个像SET
这样的关键字,尽管公认这很丑陋。
另一种选择是允许任意表达式作为=
的左操作数,从而使您的赋值规则为:
assignment -> exp (ASSIGN exp)?
这是LL(1)。 这样做的缺点是,它允许使用许多无意义的代码,例如1+2 := 42
,但是您可以在语法之外进行修复。 也就是说,您用于解析分配的代码可以简单地调用parse_exp
,然后,如果下一个标记是ASSIGN
并且parse_exp
返回的表达式不仅仅是一个标识符,则会产生一个错误,指出分配的左侧必须是一个标识符。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.