title: Useless rules and nonterminals in Bison grammar
body: <p>I have the following Bison file describing my scripting language grammar:</p>
  
  <pre><code>%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&lt;NVariableDeclaration*&gt; *variableDeclarations;
      std::vector&lt;NExpression*&gt; *expressions;
      std::vector&lt;NStatement*&gt; *statements;
      std:string *string;
      int token;
  }
  
  
  %token &lt;string&gt; TIDENTIFIER TINTEGER TDOUBLE
  %token &lt;token&gt; TCEQ TCNE TCLT TCLE TCGT TCGE TEQUAL
  %token &lt;token&gt; TLPAREN TRPAREN TLBRACE TRBRACE TCOMMA TDOT
  %token &lt;token&gt; TPLUS TMINUS TMUL TDIV TDO TDOUBLE_TYPE TINT_TYPE
  %token &lt;token&gt; TELSE TFOR TIF TSEMICOLON TTHEN TWHILE
  
  %type &lt;expression&gt; expression term factor
  %type &lt;block&gt; program body header tail statements
  %type &lt;statement&gt; statement forStatement ifStatement doWhileStatement whileStatement variableDeclaration
  %type &lt;token&gt; comparison
  %type &lt;string&gt; 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"); }
                          ; 
  </code></pre>
  
  <p>I really don't understand why I am getting errors related to useless nonterminals and useless rules.</p>
  
  <p>Running the command:</p>
  
  <pre><code>bison -d -o parser.cpp parser.y
  </code></pre>
  
  <p>I get the following errors:</p>
  
  <pre><code>$ 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
  </code></pre>