我正在寫一個flex/yacc程序,它應該使用cygwin來讀取一些令牌和簡單的語法。 我猜我的BNF語法錯了,但我似乎無法找到問題。下面是一些代碼如何在我的yacc代碼中找到減少/移位衝突?
%start statement_list
%%
statement_list: statement
|statement_list statement
;
statement: condition|simple|loop|call_func|decl_array|decl_constant|decl_var;
call_func: IDENTIFIER'('ID_LIST')' {printf("callfunc\n");} ;
ID_LIST: IDENTIFIER
|ID_LIST','IDENTIFIER
;
simple: IDENTIFIER'['NUMBER']' ASSIGN expr
|PRINT STRING
|PRINTLN STRING
|RETURN expr
;
bool_expr: expr E_EQUAL expr
|expr NOT_EQUAL expr
|expr SMALLER expr
|expr E_SMALLER expr
|expr E_LARGER expr
|expr LARGER expr
|expr E_EQUAL bool
|expr NOT_EQUAL bool
;
expr: expr ADD expr {$$ = $1+$3;}
| expr MULT expr {$$ = $1-$3;}
| expr MINUS expr {$$ = $1*$3;}
| expr DIVIDE expr {if($3 == 0) yyerror("divide by zero");
else $$ = $1/$3;}
|expr ASSIGN expr
| NUMBER
| IDENTIFIER
;
bool: TRUE
|FALSE
;
decl_constant: LET IDENTIFIER ASSIGN expr
|LET IDENTIFIER COLON "bool" ASSIGN bool
|LET IDENTIFIER COLON "Int" ASSIGN NUMBER
|LET IDENTIFIER COLON "String" ASSIGN STRING
;
decl_var: VAR IDENTIFIER
|VAR IDENTIFIER ASSIGN NUMBER
|VAR IDENTIFIER ASSIGN STRING
|VAR IDENTIFIER ASSIGN bool
|VAR IDENTIFIER COLON "Bool" ASSIGN bool
|VAR IDENTIFIER COLON "Int" ASSIGN NUMBER
|VAR IDENTIFIER COLON "String" ASSIGN STRING
;
decl_array: VAR IDENTIFIER COLON "Int" '[' NUMBER ']'
|VAR IDENTIFIER COLON "Bool" '[' NUMBER ']'
|VAR IDENTIFIER COLON "String" '[' NUMBER ']'
;
condition: IF '(' bool_expr ')' statement ELSE statement;
loop: WHILE '(' bool_expr ')' statement;
我試圖改變語句轉換成
statement:';';
,讀一個簡單的標記,以測試它是否工作,但似乎我的代碼拒絕進入語法的一部分。
另外,當我編譯它,它告訴我有18個轉換/減少衝突。我應該嘗試找到並解決所有這些問題嗎?
編輯:我編輯我的代碼使用克里斯多德的答案,試圖通過查看輸出文件來解決每個衝突。最後幾個衝突似乎位於下面的代碼中。
expr: expr ADD expr {$$ = $1+$3;}
| expr MULT expr {$$ = $1-$3;}
| expr MINUS expr {$$ = $1*$3;}
| expr DIVIDE expr {if($3 == 0) yyerror("divide by zero");
else $$ = $1/$3;}
|expr ASSIGN expr
| NUMBER
| IDENTIFIER
;
這裏是輸出文件的一部分,告訴我什麼是錯的。
state 60
28 expr: expr . ADD expr
29 | expr . MULT expr
30 | expr . MINUS expr
31 | expr . DIVIDE expr
32 | expr . ASSIGN expr
32 | expr ASSIGN expr .
ASSIGN shift, and go to state 36
ADD shift, and go to state 37
MINUS shift, and go to state 38
MULT shift, and go to state 39
DIVIDE shift, and go to state 40
ASSIGN [reduce using rule 32 (expr)]
ADD [reduce using rule 32 (expr)]
MINUS [reduce using rule 32 (expr)]
MULT [reduce using rule 32 (expr)]
DIVIDE [reduce using rule 32 (expr)]
$default reduce using rule 32 (expr)
我不明白,爲什麼會選擇第32條時,它讀取ADD,MULT,DIVIDE或其他令牌?這部分語法有什麼問題?
此外,即使上面的語法部分是錯誤的,我的編譯器是否不能正確讀取其他語法?例如,
let a = 5
應該是可讀的,但程序返回語法錯誤?
爲什麼我必須在最後添加另一個報價?另外,在我的lex代碼中,我可以讀取令牌並將其返回,所以我認爲它現在可以工作。並感謝您的調試提示! – ThunderBalls