簡體   English   中英

Bison語法中無用的規則和非終結符

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM