2012-05-28 72 views
1

你好優秀的程序員,移位減少衝突的幸福語法

我已經建立以下語法快樂(哈斯克爾):現在

P : program C    {Prog $2} 


E : int   {Num $1} 
    | ident   {Id $1} 
    | true   {BoolConst True} 
    | false   {BoolConst False} 
    | read   {ReadInput} 
    | '(' E ')'    {Parens $2} 
    | E '+' E    { Add $1 $3 } 
    | E '-' E    { Sub $1 $3 } 
    | E '*' E    { Mult $1 $3 } 
    | E '/' E    { Div $1 $3 } 
    | E '=' E    { Eq $1 $3 } 
    | E '>' E    { Gt $1 $3 } 
    | E '<' E    { Lt $1 $3 } 


C : '(' C ')'    {$2} 
    | ident assign E   {Assign $1 $3} 
    | if E then C else C  {Cond $2 $4 $6} 
    | output E    {OutputComm $2} 
    | while E do C   {While $2 $4 } 
    | begin D ';' C end  {Declare $2 $4} 
    | C ';' C    {Seq $1 $3 } 


D : D ';' D    {DSeq $1 $3 } 
    | '(' D ')'    {$2} 
    | var ident assign E  {Var $2 $4} 

,雖然環包括所有「做」後跟隨的命令。如何改變這種行爲?我已經試過%左,右%... :(

回答

1

發明2種C,一個允許測序,以及一個不這樣的事情,也許是:

Cnoseq : '(' Cseq ')' 
     | ident assign E 
     | while E do Cnoseq 

Cseq : Cnoseq ';' Cseq 
    | Cnoseq 
+0

這是唯一的解決方案嗎?需要對代碼進行重大更改:( – user1422467

+1

@ user1422467它只需要在解析器中進行更改 - 消耗解析樹的代碼應該能夠保持不變。 –

1

考慮下面的代碼片段:

while True do output 1 ; output 2 

這可以被解析爲兩種

(while True do output 1) ; (output 2) 

while True do (output 1 ; output 2) 

這種模糊性是衝突的根源。

如果您不想像@DanielWagner建議的那樣更改語法,則可以使用precedence rules來解決歧義問題。究竟如何依賴於優先級應該是什麼,但它可能是這樣的:

%right do 
%right then else 
%right ';' 

優先次序由低到高分別,所以在這種情況下,上面的例子將在後者的方式被解析。只需在標記下方但在%%行之前添加優先規則即可。