2012-07-29 178 views

回答

9

這似乎工作:

%syntax_error { 
     int n = sizeof(yyTokenName)/sizeof(yyTokenName[0]); 
     for (int i = 0; i < n; ++i) { 
       int a = yy_find_shift_action(yypParser, (YYCODETYPE)i); 
       if (a < YYNSTATE + YYNRULE) { 
         printf("possible token: %s\n", yyTokenName[i]); 
       } 
     } 
} 

它會嘗試所有可能的令牌,並打印那些適用於當前的解析器的狀態。

請注意,當不正確的令牌到來時,解析器不會立即調用syntax_error,但會嘗試減少堆棧上的內容,希望該令牌可以在之後進行移位。只有當沒有其他東西可以減少並且當前令牌不能移動時,解析器纔會調用syntax_error。這種減少會改變語法分析器的狀態,這意味着您可能會看到更少的令牌比減少之前的適用值更小。儘管錯誤報告應該足夠了。

+2

正是我所要求的!但是,您忘記了'yypParser'作爲yy_find_shift_action的第一個參數:) – 2012-10-30 15:58:13

1

沒有直接的方法可以在檸檬中生成這樣的列表。但是您可以嘗試使用Lemon工具的調試輸出以及生成的解析器的調試跟蹤來執行此操作。在調用ParseTrace函數後,生成的解析器將打印出Shifts和Reduce列表,並將其應用於輸入流。語法錯誤之前的最後一個Shift包含錯誤之前的當前狀態的編號。在* .out文件中爲您的解析器查找此狀態,並查看它的預期記號列表。