2016-11-16 20 views
0

我有以下語法(SSCCE):如何最好地處理野牛同樣規則的不同動作?

%token WORD 
%% 
program  : word word 
      ; 

word  : WORD // have to translate only for first word 
      ; 

規則word : WORD應具有動作,即對WORD令牌語義值被適當地「翻譯」的語義值的左手側,僅當這是規則program: word word中的第一個word

在野牛中這樣做的最佳做法是什麼?

我不明白如何做到這一點與行動。我必須擴展語法本身,以此:

%token WORD 
%% 
program  : word_translated word_not_translated 
      ; 

word_translated  : WORD { // translate } 
      ; 

word_not_translated : WORD { // do not translate } 
      ; 

好的,但是我不喜歡。因爲語法有兩個符號word_translatedword_not_translated,就語法而言,它們完全一樣,所以語法太複雜了,應該簡化成一個word。增加複雜性的唯一原因是,行動可能會有所不同。

這是做到這一點的唯一方法,這是野牛處理這種情況的最佳做法嗎?

+1

是的,這是最好的做法 - 當你需要做同樣的符號不同的動作(終端或非終端)的不同的上下文,你只需創建一個新的單例規則。 –

+0

@Chris好的謝謝你,但在此期間,我想出瞭如何做到這一點:使用'$ 0' –

+0

@ChrisDodd我發現了全面的情況,而不是我的帖子中簡單的SSCCE,使用' $ 0','$ -1'等是不切實際的。它真的就像自己構建樹並走路。所以你的評論是黃金。你應該讓它成爲我會接受的答案。 –

回答

1

語義操作最好從任何編譯器或解釋器中的分析樹來執行。如果您試圖從野牛規則動作中執行語言語義行爲方向,您將永遠陷入你描述的那種混亂狀態。

只要在野牛行動中構建一個分析樹,然後在樹完全知道後採取適當的語義行爲來行走樹。大多數標準的編譯器文本都有工作示例。

+0

謝謝!但我不明白這一點。我想我知道什麼是「解析樹」,根據野牛手冊和yacc/bison文本,解析樹是野牛構建的,它不適合我在野牛行動中構建它,就像你似乎建議。野牛行動是對野牛建造的分析樹進行反應。在我的情況下,就詞法分析器而言,這兩個WORD令牌是完全一樣的 - 它們不能由詞法分析器區分。 –

+0

@MarkGaleck其他解析器生成器具有構建樹的功能,但bison/yacc不具備這些功能。它必須手動編碼。我爲我的學生製作了一個教學視頻[https://youtu.be/oOFfVZrvhMA?list=PL3czsVugafjNLmIHA8ODBxuwWy8W4Uk9h] –

+0

謝謝!我觀看了您的視頻並仔細閱讀了野牛文檔 - 事實上,我錯了,野牛不會建樹。在視頻中,它展示瞭如何構建分析樹,這對學生來說是一個很棒的視頻,但對我來說,很明顯,不需要解釋。對我來說這個問題是「爲什麼」我需要一個解析樹。我發現在其他應用程序中可能需要構建和行走樹,並且我發現在我的情況下我可以這樣做來解決我的問題。但就我而言,這將是一種矯枉過正,甚至比我的帖子還要複雜。我的應用程序中不需要樹。見下文。 –

-1

我會恭敬地不同意Brian的斷言,野牛動作應該只用來建立一個解析樹,然後解析後,樹應該走,在這期間,應該採取真正的行動。否則,一個「總是陷入混亂」。

如果是這樣的話,經典奧賴利YACC文本不會說:「通常情況下,動作代碼生成對應 輸入解析樹,這樣以後的代碼可以處理整個語句或甚至整個 程序一次「。不是「經常」,而是說「永遠」。

但是,布賴恩的答案在這方面非常有用,在試圖理解它時,我不得不閱讀。然後,我發現恕我直言正確的答案,我的問題,因爲它張貼。我會爲未來瀏覽器的好處發佈答案。

恕我直言,正確的方法是使用$0。隨着我的帖子原來的語法,該操作的僞代碼將是:

if ($0 is meaningful) 
    $$ = $1 
else 
    $$ = translate($1) 
+0

野牛手冊對使用'$ 0 $'說明:「這是一個非常冒險的做法,爲了可靠地使用它,您必須確定規則應用的上下文。」目前還不完全清楚你如何在不以某種方式冒險進入未定義行爲的情況下驗證「$ 0是否有意義」。它可能適用於某個特定架構的特定應用程序等,但它不是一種在不清楚其侷限性的情況下應該使用的技術。 – rici

+0

@rici我不是在與「風險」部分爭論。但我不同意「目前尚不清楚你如何提出驗證意見」。很簡單。看看我的SSCCE。應用程序代碼可以將'yylval'初始化爲一個無效值,或者可以將其聲明爲'static'並且已知有零位的初始化。 'translate'函數返回一個有效的非零值。這很簡單,不是嗎? –

+0

只能工作一次。是的,在你的微不足道的語法中,這是可能的,但如果'程序'不是最高級別的非終端,那麼對'yylval'具有的值的控制就會少得多。對於語法如此微不足道的野牛來說,這並不值得,所以我認爲你實際上已經有了一些更復雜的想法,就像任何人在這個問題上磕磕絆絆一樣。你在代碼中所做的事絕對是你的擔心,我無意試圖勸阻你。我的評論和downvote是試圖給其他讀者附加健康警告。 – rici