2014-12-04 45 views
0

我有以下一段代碼:解析基於壓痕語法(如Python)與YECC

case 1 
of 2 
    3 
of 3 
    4 
5 

那我的自定義標記生成器轉換爲:

Tokens: [{'case',1}, 
     {integer,1,1}, 
     {eol,1}, 
     {'of',1}, 
     {integer,1,2}, 
     {block,[{integer,1,3}]}, 
     {eol,1}, 
     {'of',1}, 
     {integer,1,3}, 
     {block,[{integer,1,4}]}, 
     {eol,1}, 
     {integer,1,5}] 

但後來我不是能夠與以下Yecc解析它:

Nonterminals 
    grammar 
    statements statement 
    case_def case_conditions condition. 


Terminals 
    eol block 
    integer 
    case of. 


Rootsymbol grammar. 


grammar -> statements : '$1'. 


statements -> statement eol statements : ['$1'|'$3']. 
statements -> statement : ['$1']. 

statement -> case_def : '$1'. 
statement -> integer : '$1'. 


case_def -> 'case' integer case_conditions : ''. 

case_conditions -> case_condition case_conditions : ['$1'|'$2']. 
case_conditions -> case_condition : ['$1']. 

case_condition -> eol 'of' integer block : ''. 

它給了我下面的輸出:

["syntax error before: ","5"] 

任何幫助真的歡迎,謝謝。

回答

1

我認爲在非終端列表,你應該有case_condition代替condition

您的自定義掃描儀忽略縮進。它發出令牌INDENTDEDENT。我找到了example in yacc。然後你可以改變你的語法來使用這些令牌。

你的榜樣產生移位/減少衝突。文檔說:

如果存在 沒有運算符優先級聲明,則轉換/減少衝突得到解決以支持轉換。

這意味着,當你的解析器是由|

of 3 
    4| 
5 

表示的地方,看到新的生產線,可能有兩種選擇:

  • ,這可能是未來case_condition如此解析器需要繼續「移動」以閱讀更多
  • 這可能是語句的結尾,因此解析器需要在處理語句之前處理所有內容並將其放入在堆棧或簡稱「減少」

因爲這些衝突總是解決轉移,你不能把下一個語句後,你開始案例!你需要改變你的語法。使用它直到yecc:file/1不會產生任何警告。

提示:縮進裏面的一切情況是這樣的:

case 1 
    of 2 
     3 
    of 3 
     4 
5 

通過這種方式,你都清楚地告訴我們說,case是一個聲明,5是另一回事。我對解析器的瞭解有點生疏,但我相信,如果不添加縮進或某種類型的終止符,您將無法使用從左到右的解析器編寫區分case_conditionstatement的語法。