[英]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.