0

我想为算术方程和变量赋值设计一个 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
4

1 回答 1

1
assignment -> ID ASSIGN expr | expr

(我忽略了这typ部分,因为我认为它是偶然到达那里的)

这里的问题是两者都ID ASSIGN expr可以expr从一个开始ID(或者至少它们可以作为一个选项T包含ID,我认为这是意图),所以这不是 LL(1)。虽然它是 LL(2),所以如果你对此感到满意,你可以在你的解析器中添加一个andalso next_token = ASSIGN条件if并完成它。

如果您确实需要它是 LL(1),那么恐怕您必须调整解析器允许的语言(也就是说,没有 LL(1) 语法与您当前的语言完全相同语法)。一种简单的方法是SET在赋值之前简单地添加一个关键字,尽管不可否认这很难看。

另一种选择是允许任意表达式作为 的左操作数=,从而制定您的分配规则:

assignment -> exp (ASSIGN exp)?

这是LL(1)。这样做的缺点是它允许大量无意义的代码,例如1+2 := 42,但您可以在语法之外修复它。也就是说,您用于解析赋值的代码可以简单地调用parse_exp,然后,如果下一个标记是 anASSIGN并且返回的表达式parse_exp不仅仅是一个标识符,则引发一个错误,即赋值的左侧必须是一个标识符。

于 2018-11-10T16:20:19.997 回答