讓我首先提出問題:我可以將實現此特定語法的解析樹簡單地轉換爲AST。將解析樹轉換爲AST
我被賦予此語法構建解析樹:
literal := INTEGER | FLOAT | TRUE | FALSE .
designator := IDENTIFIER { "[" expression0 "]" } .
op0 := ">=" | "<=" | "!=" | "==" | ">" | "<" .
op1 := "+" | "-" | "or" .
op2 := "*" | "/" | "and" .
expression0 := expression1 [ op0 expression1 ] .
expression1 := expression2 { op1 expression2 } .
expression2 := expression3 { op2 expression3 } .
expression3 := "not" expression3
| "(" expression0 ")"
| designator
| call-expression
| literal .
對於這個特定的例子:
func main() : void {
let a = 1 + 2 + 3 + 4;
}
我的解析器將生成(部分)的解析樹來
EXPRESSION1
EXPRESSION2
EXPRESSION3
LITERAL
INTEGER(1)(lineNum:2, charPos:10)
OP1
ADD(lineNum:2, charPos:12)
EXPRESSION2
EXPRESSION3
LITERAL
INTEGER(2)(lineNum:2, charPos:14)
OP1
ADD(lineNum:2, charPos:16)
EXPRESSION2
EXPRESSION3
LITERAL
INTEGER(3)(lineNum:2, charPos:18)
OP1
ADD(lineNum:2, charPos:20)
EXPRESSION2
EXPRESSION3
LITERAL
INTEGER(4)(lineNum:2, charPos:22)
只需注意EXPRESSION1下的這些樹分支如何去:
EXPRESSION2 + EXPRESSION2 + EXPRESSION2 + EXPRESSION2
其中operator +不對應於它的兩個操作數。因此,在我看來,在AST轉換中,我無法獲得一個AST,它通過簡單地拉起操作員來替換非終端EXPRESSION1來幫助生成3位地址IR代碼。
爲了實現這個目標,我會爲這種語言所編寫的語法會是這樣,而不是
expression1 := expression2 | expression1 + expression2 (1)
expression2 := expression3 | expression2 * expression3 (2)
expression3 := literal (3)
該表達式下的分支是唯一
EXPRESSION1 + EXPRESSION2
然而,這個語法是不LL(1)自| FIRST(expression2)| = | {literal,+} | > 1.
它引發了一個問題:(1)轉換這個分析樹最優雅和最簡單的方法是什麼? (2)是我的語法分析樹的構造完全浪費了時間,我應該開始編寫AST代碼了?
您可能會考慮分析樹和抽象語法樹之間的真正區別。看到我的回答:http://stackoverflow.com/questions/1888854/what-is-the-difference-between-an-abstract-syntax-tree-and-a-concrete-syntax-tre/1916687#1916687 –
這似乎非常好。我聽說過關於GLR的一些不錯的屬性。現在,科學技術委員會得到了壓縮。感謝您的信息。 – Davis
嗯,這是我在截止日期之前無法弄清楚的一些學校作業。我必須遵循一些具體的指導原則。我太愚蠢了,沒有意識到目標AST不僅僅是CST的「簡化」版本,而是表達語法存在問題。樹結構是不同的。我只是有點生氣。 – Davis