2017-02-15 130 views
0

我試圖運行此文件.Y野牛語法錯誤易文件

%{ 
#include <stdlib.h> 
#include <stdio.h> 
int yylex(); 
int yyerror(); 

%} 

%start BEGIN 

%% 

BEGIN: 'a' | BEGIN 'a' 


%% 

int yylex(){ 
    return getchar(); 
} 

int yyerror(char* s){ 
    fprintf(stderr, "*** ERROR: %s\n", s); 
    return 0; 
} 

int main(int argn, char **argv){ 
    yyparse(); 
    return 0; 
} 

這是野牛一個簡單的程序,語法在我看來是正確的,但總是得到語法錯誤的問題... 謝謝你的幫助。

回答

1

詞法分析函數yylex需要返回0來指示輸入的結束。但是,您的實現只需傳遞getchar返回的值,即EOF(通常爲-1)。

此外,您的輸入幾乎肯定會包含換行符,該換行符也將傳遞給解析器。

由於解析器既不識別\n也不識別EOF,它在接收到其中一個時會產生錯誤。

在最低限度,你就需要修改yylex正確響應最終輸入:

int yylex(void) { 
    int ch = getchar(); 
    return (ch == EOF) ? 0 : ch; 
} 

但你仍然會有,無論是在你的詞法分析器處理它們來處理換行符charactets(可能忽略他們或可能返回輸入imdication結束),或通過在您的語法中處理它們。

請注意,bison/yacc生成的解析器總是解析整個輸入流,而不僅僅是滿足語法的最長序列。這可以通過一些工作進行調整 - 請參閱YYACCEPT特殊操作的文檔 - 但標準行爲通常是解析時需要的。

順便說一下,請在您的bison/yacc語法中使用標準樣式約定,以避免出現問題並避免讓讀者感到困惑。通常我們爲終端符號保留UPPER_CASE,因爲它們在詞法分析器中也被用作編譯時常量。非終端通常寫在lower_case,儘管有些人喜歡使用CamelCase。對於終端,您需要避免使用標準庫保留的名稱(如EOF)或(f)lex(BEGIN)或bison/yacc(END)。手冊中有保留名稱列表。