Bison - 为什么这会为所有输入产生语法错误
Bison - why this is producing syntax error for all inputs
我写了一个简单的语法:
expr:
INT { $$ = intc(); }
| FLOAT { $$ = floatc(); }
| STR { $$ = strc(); }
| ID { $$ = id(, false); }
| ID '=' expr { $$ = operate('=', id(, false), ); }
| VAR ID { $$ = id(, true); }
| VAR ID '=' expr { $$ = operate('=', id(, true), ); }
| '-' expr %prec NEG { $$ = operate(NEG, , NULL); }
| expr '+' expr { $$ = operate('+', , ); }
| expr '-' expr { $$ = operate('-', , ); }
| expr '*' expr { $$ = operate('*', , ); }
| expr '/' expr { $$ = operate('/', , ); }
| '(' expr ')' { $$ = ; }
;
stmt:
';' {}
| expr ';' { compile(); }
;
prog:
prog stmt {}
|
;
其中 INT、FLOAT 和 STR 是分别对应整数、浮点数和字符串文字的词法标记,ID 是有效标识符,VAR 是首次使用标识符的声明符。
但是这个 bison 文件显示了这些警告:
lang.y: warning: 2 nonterminals useless in grammar [-Wother]
lang.y: warning: 4 rules useless in grammar [-Wother]
lang.y:73.1-4: warning: nonterminal useless in grammar: stmt [-Wother]
stmt:
^^^^
lang.y:78.1-4: warning: nonterminal useless in grammar: prog [-Wother]
prog:
^^^^
lang.y:74.9-14: warning: rule useless in grammar [-Wother]
';' {}
^^^^^^
lang.y:75.11-35: warning: rule useless in grammar [-Wother]
| expr ';' { compile(); }
^^^^^^^^^^^^^^^^^^^^^^^^^
lang.y:79.9-20: warning: rule useless in grammar [-Wother]
prog stmt {}
^^^^^^^^^^^^
lang.y:80.10: warning: rule useless in grammar [-Wother]
|
^
lang.y: warning: 19 shift/reduce conflicts [-Wconflicts-sr]
每当我输入以分号结尾的语句时,它也会产生 syntax error, unexpected ';'
错误。如果我在第一行不使用分号,那么当我输入第二行时,它会产生 syntax error, unexpected <FIRST_TOKEN_IN_SECOND_LINE>
.
所以有人请帮助我,指出我哪里做错了。
解析从语法的非终结符开始。如果您不使用 %start
设置开始规则,语法中定义的第一个非终结符将是您的开始规则。
所以在你的语法中,开始非终结符将是 expr
。所以你的输入会产生语法错误,因为它们不匹配 expr
而你的其他非终端是无用的,因为它们从未被 expr
.
使用过
如果您希望解析以 prog
开头,您需要添加指令 %start prog
或将 prog
移动到语法的开头。
我写了一个简单的语法:
expr:
INT { $$ = intc(); }
| FLOAT { $$ = floatc(); }
| STR { $$ = strc(); }
| ID { $$ = id(, false); }
| ID '=' expr { $$ = operate('=', id(, false), ); }
| VAR ID { $$ = id(, true); }
| VAR ID '=' expr { $$ = operate('=', id(, true), ); }
| '-' expr %prec NEG { $$ = operate(NEG, , NULL); }
| expr '+' expr { $$ = operate('+', , ); }
| expr '-' expr { $$ = operate('-', , ); }
| expr '*' expr { $$ = operate('*', , ); }
| expr '/' expr { $$ = operate('/', , ); }
| '(' expr ')' { $$ = ; }
;
stmt:
';' {}
| expr ';' { compile(); }
;
prog:
prog stmt {}
|
;
其中 INT、FLOAT 和 STR 是分别对应整数、浮点数和字符串文字的词法标记,ID 是有效标识符,VAR 是首次使用标识符的声明符。
但是这个 bison 文件显示了这些警告:
lang.y: warning: 2 nonterminals useless in grammar [-Wother]
lang.y: warning: 4 rules useless in grammar [-Wother]
lang.y:73.1-4: warning: nonterminal useless in grammar: stmt [-Wother]
stmt:
^^^^
lang.y:78.1-4: warning: nonterminal useless in grammar: prog [-Wother]
prog:
^^^^
lang.y:74.9-14: warning: rule useless in grammar [-Wother]
';' {}
^^^^^^
lang.y:75.11-35: warning: rule useless in grammar [-Wother]
| expr ';' { compile(); }
^^^^^^^^^^^^^^^^^^^^^^^^^
lang.y:79.9-20: warning: rule useless in grammar [-Wother]
prog stmt {}
^^^^^^^^^^^^
lang.y:80.10: warning: rule useless in grammar [-Wother]
|
^
lang.y: warning: 19 shift/reduce conflicts [-Wconflicts-sr]
每当我输入以分号结尾的语句时,它也会产生 syntax error, unexpected ';'
错误。如果我在第一行不使用分号,那么当我输入第二行时,它会产生 syntax error, unexpected <FIRST_TOKEN_IN_SECOND_LINE>
.
所以有人请帮助我,指出我哪里做错了。
解析从语法的非终结符开始。如果您不使用 %start
设置开始规则,语法中定义的第一个非终结符将是您的开始规则。
所以在你的语法中,开始非终结符将是 expr
。所以你的输入会产生语法错误,因为它们不匹配 expr
而你的其他非终端是无用的,因为它们从未被 expr
.
如果您希望解析以 prog
开头,您需要添加指令 %start prog
或将 prog
移动到语法的开头。