[英]Useless rules and nonterminals in Bison grammar
我有以下Bison文件描述了我的脚本语言语法:
%error-verbose
%{
#include "node.h"
NBlock *programBlock;
#define YYDEBUG 1
extern int yylex();
void yyerror(const char *) { printf("Error: %s\n", s); }
%}
%union {
Node *node;
NBlock *block;
NBody *body;
NHeader *header;
NExpression *expression;
NStatement *statement;
NIdentifier *identifier;
NVariableDeclaration *variableDeclaration;
NDoWhileStatement *doWhileStatement;
NWhileStatement *whileStatement;
NIfStatement *ifStatement;
NForStatement *forStatement;
std::vector<NVariableDeclaration*> *variableDeclarations;
std::vector<NExpression*> *expressions;
std::vector<NStatement*> *statements;
std:string *string;
int token;
}
%token <string> TIDENTIFIER TINTEGER TDOUBLE
%token <token> TCEQ TCNE TCLT TCLE TCGT TCGE TEQUAL
%token <token> TLPAREN TRPAREN TLBRACE TRBRACE TCOMMA TDOT
%token <token> TPLUS TMINUS TMUL TDIV TDO TDOUBLE_TYPE TINT_TYPE
%token <token> TELSE TFOR TIF TSEMICOLON TTHEN TWHILE
%type <expression> expression term factor
%type <block> program body header tail statements
%type <statement> statement forStatement ifStatement doWhileStatement whileStatement variableDeclaration
%type <token> comparison
%type <string> identifier_type
%left TPLUS TMINUS
%left TMUL TDIV
%start program
%%
program: TLBRACE body TRBRACE { printf("Reduce body to program\n"); }
;
body: header TLBRACE block TRBRACE tail { printf("Reduce header block tail to body\n"); }
;
header: TLBRACE variableDeclarations TRBRACE { printf("Reduce variableDeclarations to header\n"); }
| TLBRACE TRBRACE { printf("Reduce empty to header\n"); }
;
variableDeclarations: variableDeclaration TSEMICOLON { printf("Reduce variable declaration to header\n"); }
| variableDeclarations variableDeclaration TSEMICOLON { printf("Reduce variable declaration list to header\n"); }
;
tail: TLBRACE statements TRBRACE { printf("reduce statement list to tail\n"); }
| TLBRACE TRBRACE { printf("Reduce empty to tal\n"); }
;
statements: statement TSEMICOLON { printf("Reduce statement to statement list\n"); }
| statements statement TSEMICOLON { printf("Reduce statement list to statement list\n"); }
;
statement: ifStatement { printf("Reduce if to statement\n"); };
| forStatement { printf("Reduce for to statement\n"); };
| doWhileStatement { printf("Reduce doWhile to statement\n"); };
| whileStatement { printf("reduce while to statement\n"); }
| expression { printf("Reduce expression to statement\n"); };
;
forStatement: TFOR TLPAREN expression TSEMICOLON expression TSEMICOLON expression TRPAREN block { printf("Reduce for to for statement\n"); }
;
ifStatement: TIF expression TTHEN block { printf("Reduce if to if statement\n"); }
| TIF expression block TELSE block { printf("Reduce ifelse to if statement\n"); }
;
doWhileStatement: TDO block TWHILE expression { printf("reduce dowhile to while statement\n"); }
;
whileStatement: TWHILE block expression { printf("Reduce while to while statement\n"); }
;
block: TLBRACE statements TRBRACE { printf("Reduce statement list to block\n"); }
| TLBRACE TRBRACE { printf("Reduce empty to block\n"); }
;
variableDeclaration: identifier_type TIDENTIFIER { printf("reduce uninitialized identifier to variable declaration\n"); }
| identifier_type TIDENTIFIER TEQUAL expression { printf("Reduce initialized identifier to variable declaration\n"); }
;
identifier_type: TINT_TYPE { printf("Reduce int to identifier type\n"); }
| TDOUBLE_TYPE { printf("Reduce double to identifier type\n"); }
| { printf("Reduce empty to identifier type\n"); }
;
expression: TIDENTIFIER TEQUAL expression { printf("Reduce assignment to expression\n"); }
| TIDENTIFIER { printf("reduce identifier to expression\n"); }
| expression comparison expression { printf("Reduce comparison to expression\n"); }
| TLPAREN expression TRPAREN { printf("Reduce nested expression to expression\n"); }
| expression TPLUS term { printf("Reduce addition to expression\n"); }
| expression TMINUS term { printf("Reduce subtraction to expression\n"); }
| term { printf("Reduce term to expresson\n"); }
| factor { printf("Reduce factor to expression\n"); }
;
term: term TMUL factor { printf("Reduce multiplication to term\n"); }
| term TDIV factor { printf("Reduce division to term\n"); }
;
factor: TIDENTIFIER { printf("Reduce identifier to factor\n"); }
| TINTEGER { printf("Reduce integer to numeric\n"); }
| TDOUBLE { printf("Reduce double to numeric\n"); }
;
comparison: TCEQ { printf("Reduce eq to comparison\n"); }
| TCNE { printf("Reduce ne to comparison\n"); }
| TCLT { printf("Reduce lt to comparison\n"); }
| TCLE { printf("Reduce le to comparison\n"); }
| TCGT { printf("reduce gt to comparison\n"); }
| TCGE { printf("Reduce ge to comparison\n"); }
| TPLUS { printf("Reduce plus to comparison\n"); }
| TMINUS { printf("Reduce minus to comparison\n"); }
| TMUL { printf("Reduce mul to comparison\n"); }
| TDIV { printf("Reduce div to comparison\n"); }
;
我真的不明白为什么我会收到与无用的非终结符和无用的规则有关的错误。
运行命令:
bison -d -o parser.cpp parser.y
我收到以下错误:
$ bison -d -o parser.cpp parser.y
parser.y: attention: 1 nonterminal useless in grammar
parser.y: attention: 5 rules useless in grammar
parser.y:52.31-34: attention: nonterminal useless in grammar: term
parser.y:135.51-118: attention: rule useless in grammar: expression: expression TPLUS term
parser.y:136.51-123: attention: rule useless in grammar: expression: expression TMINUS term
parser.y:137.51-96: attention: rule useless in grammar: expression: term
parser.y:141.41-103: attention: rule useless in grammar: term: term TMUL factor
parser.y:142.51-107: attention: rule useless in grammar: term: term TDIV factor
parser.y: conflicts: 20 shift/reduce, 14 reduce/reduce
parser.y:145.41-96: attention: rule useless in parser due to conflicts: factor: TIDENTIFIER
我认为冲突是解析器在找到TIDENTIFIER时将不知道选择哪个规则。 原因是
TIDENTIFIER
可以简化为expression
factor
可以简化为expression
TIDENTIFIER
可降至factor
因此,当解析器获得标识符时,它可以通过两种方式到达表达式。
TIDENTIFIER -> expression
TIDENTIFIER -> factor -> expression
我薄你的情况,你可以安全地删除TIDENTIFIER
从因素,因为factor
被减少到只有 expression
反正。
但是,更合适的方法(至少对于大多数通用语言而言)可能是让TIDENTIFIER
成为factor
并在statement
处理其余的factor
。 例如, TIDENTIFIER ASSIGN expression
可以是有效statement
。
顺便说一句,您的statement
包括expression
。 可能不是您的预期。 statement
应始终与expression
不同(毕竟这就是为什么需要两个规则的原因)。
我认为您应该检查类似的情况。 如果您有一个仅使用其他规则的规则(没有任何其他标记或其他规则),则可能是错误的。 从某种意义上说这不是您想要的,这是错误的 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.