2017-03-09 81 views
2

我是新來的野牛,我試圖做一個文法解析表達式。 我現在面臨着一種轉變/減少困惑,我無法解決。解決表達語法中的移位/減少衝突

語法如下:

%left "[" "(" 
%left "+" 

%% 

expression_list : expression_list "," expression 
       | expression 
       | /*empty*/ 
       ; 


expression : "(" expression ")" 
      | STRING_LITERAL  
      | INTEGER_LITERAL   
      | DOUBLE_LITERAL 
      | expression "(" expression_list ")" /*function call*/ 
      | expression "[" expression "]" /*index access*/ 
      | expression "+" expression   
      ; 

這是我的語法,但我面對的轉變/減少與這兩個規則"(" expression ")"expression "(" expression_list ")"衝突。 我該如何解決這個衝突?

編輯:我知道我可以使用優先級攀登來解決這個問題,但我不想這樣做,因爲這只是表達式語法的一小部分,而表達式語法的大小會使用優先級爬升爆炸。

+0

如果這是您的語法的整體,它沒有轉換 - 減少衝突。但是,我懷疑這是你的整個語法。 – rici

+0

哇我現在覺得真是愚蠢......我在另一條規則中發現了一個錯字,這影響了這一條 – Exagon

+0

這就是爲什麼我們要求[mcve],這與「我的代碼的幾行」有很大不同。如果您製作[mcve],它通常會幫助您澄清問題,爲您解決問題。 – rici

回答

2

語法中沒有如所介紹的移位 - 縮減衝突,所以我想這只是完整語法的摘錄。特別是,將有準確的移進/歸約衝突中提到,如果真正的語法包括:

%start program 
%% 
program: %empty 
     | program expression 

在這種情況下,你會遇到歧義,因爲給出的,例如,a(b),解析器無法分辨它是否是單個調用表達式或兩個連續表達式,第一個是單個變量,第二個是括號表達式。爲了避免這個問題,你需要有一些令牌來區分表達式(語句)。

還有其他一些問題:

expression_list : expression_list "," expression 
       | expression 
       | /*empty*/ 
       ; 

,允許表達式列表是,foo(如在f(,foo)),這很可能不期望的。更好的是

arguments: %empty 
     | expr_list 
expr_list: expr 
     | expr_list ',' expr 

而且優先級可能倒退。通常情況下,人們希望像調用和索引這樣的後綴運算符比算術運算符更緊密地綁定,所以它們應該結束。否則a+b(7)(a+b)(7),這是非常規的。

+0

你是對的,我很抱歉 – Exagon