我正在嘗試用Yecc編寫一個Erlang解析器,但我在語義規則的優先級上遇到了一些麻煩。在我的例子中,我定義了語法,終端和非終端符號,規則和相關的代碼。Erlang的Yecc優先問題
這是我寫的測試。
%Grammar non terminals
Nonterminals product require require1 mandatory mandatory1.
%Grammar terminals
Terminals 'tick' 'feature' '(' ')' 'req' 'mand' ';' 'nil'.
%Initial symbol
Rootsymbol product.
%Operands priority
Left 200 require.
Left 190 require1.
Left 180 mandatory.
Left 170 mandatory1.
Left 80 'req'.
Left 60 'mand'.
Left 50 ';'. %Secuence
Left 40 'feature'. %Optional feature
%--------------------------------------------------
%Grammar with operational rules
%[req1 & req2]
product -> require: '$1'.
require -> feature req feature '(' feature ';' product ')' : if
'$1' == '$5' -> {'$5', {'$4', '$7', '$8', {mand,1}, '$3'}};
true -> {'$5', {'$1', '$2', '$3', '$4', '$7', '$8'}}
end.
%[req3]
product -> require1 : '$1'.
require1 -> feature req feature '(' tick ')' : {nil,1}.
%[mand2 & mand3]
product -> mandatory : '$1'.
mandatory -> '(' feature ';' product ')' mand feature : if
'$2' == '$7' -> {'$2', {'$4'}};
true -> {'$2',{'$1', '$4', '$5', '$6', '$7'}}
end.
%[mand1]
product -> mandatory1: '$1'.
mandatory1 -> '(' tick ')' mand feature : {$5, {tick,1}}.
%[tick]
product -> feature ';' tick : {'$1', {nil,1}}.
product -> nil.
product -> feature ';' product : {'$1', {'$3'}}.
Erlang code.
%To remove brackets and return only the third parameter, right now is not used.
unwrap_feature({_,_,V}) -> V.
%%How to compile and use
%Save this as stack.yrl
%Run erl and then
%yecc:yecc("stack.yrl","stack.erl").
%c(stack).
現在讓我們執行一個特定的術語來檢查規則是如何應用的。
stack:parse([{feature,1,'A'},{'req',1},{feature,1,'C'},{'(',1},{feature,1,'A'},{';',1},{feature,1,'B'},{';',1},{feature,1,'C'},{';',1},{tick,1},{')',1}]).
解析器輸出是:
{ok,{{feature,1,'A'},
{{'(',1},
{{feature,1,'B'},{{{feature,1,'C'},{nil,1}}}},
{')',1},
{mand,1},
{feature,1,'C'}}}}
但我需要這個。只要解析器處理該術語(如調試輸出),我就會寫輸出。
初始期限。
{feature,1,'A'},{'req',1},{feature,1,'C'},{'(',1},{feature,1,'A'},{';',1},{feature,1,'B'},{';',1},{feature,1,'C'},{';',1},{tick,1},{')',1}
規則%[req1 & req2]。 (這是正確應用 - 案例「$ 1」 ==「$ 5」)
{feature,1,'A'},{{'(',1},{feature,1,'B'},{';',1},{feature,1,'C'},{';',1},{tick,1},{')',1},{mand,1},{feature,1,'C'}}
現在,我不知道會發生什麼,但輸出應該不過的了。
規則%[mand2 & mand3]。 (情況真)
{feature,1,'A'},{{feature,1,'B'},{{'(',1},{feature,1,'C'},{';',1},{tick,1},{')',1},{mand,1},{feature,1,'C'}}}
規則%[mand2 & mand3]。 (案例'$ 2'=='$ 7')
{feature,1,'A'},{{feature,1,'B'},{{feature,1,'C'},{{tick,1}}}}
規則%[tick] - 和最終結果。
{feature,1,'A'},{{feature,1,'B'},{{feature,1,'C'},{{{tick,1},{nil,1}}}}}
我已經嘗試過這樣的:
由於Yecc手冊中解釋,我能做到這一點:
- 與運算符優先播放。
- 將規則應用於優先級。 從文檔(也可以聲明優先級爲 非終端,「上一級」。當操作員重載 (參見下面的示例3)時,這是實用的)。
但它似乎並沒有爲我工作。任何幫助?
謝謝!
嗨!感謝您的回答。 1-我只是在require ,require1,mandatory和mandatory1這兩個術語的優先部分中放了一些權重,以查看是否改變了解析器的行爲(不起作用:(): 2- require,require1,mandatory和mandatory1是輔助術語,也用於檢查是否通過添加一些權重優先級可以改變解析器的行爲(如文檔中詳述的) 3-您的意思是{mand,1} ??這是因爲y想要改變該術語使其符合其他規則。首先它沒有{mand,1}而不是{req,1},因此它符合一些或其他規則。 – ccamacho
這是文檔的參考文獻 「這是當操作員超載時也很實用(參見下面的示例3)「,http://erldocs.com/R14B01couch/parsetools/yecc.html – ccamacho