繁体   English   中英

LL1语法用于算术表达式和赋值

[英]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 exprexpr都可以以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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM