Shift Reduce Conflict in Bison Grammar
<p>I have just started working with Bison and I am facing a couple of issues. The goal of my grammar is to recognize a "command pipeline" language where the output of one command can be piped as the input of another command. Each command can also have a list of parameters with an optional value. Here is an example:</p>

<pre><code>command1 --param1 test --param2 test2 | command2 | command3 --param3
</code></pre>

<p>In the previous example, <code>command1</code> takes two parameters, <code>param1</code> with value <code>test</code> and <code>param2</code> with value <code>test2</code>. The output of <code>command1</code> is then "piped" to <code>command2</code>, which takes no parameters. Finally the result of <code>command2</code> is piped to <code>command3</code>, which takes one parameter (parameters with no value are considered as a switch).</p>

<p>The corresponding bison grammar is given below:</p>

<pre><code>%{

#include &lt;string&gt;
#include &lt;iostream&gt;
#include "AST.h"
#include "Evaluator.h"

void yyerror (const char *error);
int  yylex();

%}

%code{
    Evaluator eval;
}

%union {
  char* s;
  double d;
  AbstractNode* abstractnode;
  CmdletCall* cmdletdef;
  ParameterDef* parameterdef;
  ParameterListDef* paramlistdef;
}

/* declare tokens */

%token EOL
%token&lt;s&gt; PARAMETERNAME
%token&lt;s&gt; BUILTIN
%token&lt;s&gt; IDENTIFIER


%type &lt;parameterdef&gt; parameterDef
%type &lt;cmdletdef&gt; cmdletCall
%type &lt;abstractnode&gt; pipeLineDef    
%type &lt;paramlistdef&gt; paramList
%%

input: /* nothing */
    | input pipeLineDef EOL {
                                $2-&gt;accept(eval);
                                delete $2;
                                std::cout &lt;&lt; eval.result() &lt;&lt; std::endl;
                            }                        
    | input EOL             {}
    ;



pipeLineDef: cmdletCall                  {$$ = $1;}      
    | pipeLineDef '|' cmdletCall         {$$ = new PipeLineDef($1, $3);}   
    ;


cmdletCall: IDENTIFIER                   {$$ = new CmdletCall($1);}                 
          | cmdletCall paramList         {$1-&gt;setParameterList($2);}   
          ;

paramList: parameterDef                 {  
                                            $$ = new ParameterListDef;
                                            $$-&gt;addChildNode($1);
                                        }  
         | paramList parameterDef       {
                                            $1-&gt;addChildNode($2);
                                            $$ = $1;
                                        }
         ;

parameterDef: PARAMETERNAME             {$$ = new ParameterDef($1);}
            | parameterDef IDENTIFIER   {
                                            $1-&gt;setValue($2);
                                        }         

            ;




%%


void yyerror (const char *error)
{
  std::cout &lt;&lt; error &lt;&lt; std::endl;
}
</code></pre>

<p>The previous grammar has one shift-reduce conflict, which is reproduced below:</p>

<pre><code>Terminals unused in grammar

BUILTIN

State 10 conflicts: 1 shift/reduce
State 10

7 cmdletCall: cmdletCall paramList .
9 paramList: paramList . parameterDef

PARAMETERNAME  shift, and go to state 9

PARAMETERNAME  [reduce using rule 7 (cmdletCall)]
$default       reduce using rule 7 (cmdletCall)

parameterDef  go to state 13
</code></pre>

<p>I would like to remove the conflict but I am not sure how I should proceed (my understanding is that a shift/reduce conflict indicates an ambiguous grammar). However, from my initial tests, everything seems to work as expected.
Another point that puzzles me is the way Bison evaluates the terminals. For example, if I rewrite the <code>cmdletCall</code> and <code>paramList</code> rules as follows, the grammar breaks:</p>

<pre><code>cmdletCall: IDENTIFIER paramList         {$$ = new CmdletCall($1);    $$-&gt;setParameterList($2);}   
          ;

paramList: /*nothing*/ 
                                        {  
                                            $$ = new ParameterListDef;

                                        }  
         | paramList parameterDef       {
                                            $1-&gt;addChildNode($2);
                                            $$ = $1;
                                        }
         ;
</code></pre>

<p>If I rewrite the grammar as shown above, then for an input such as:</p>

<pre><code>command1 --param1
</code></pre>

<p>In the <code>cmdletCall</code> rule, The value of <code>$1</code>, which corresponds to the <code>IDENTIFIER</code> token, will be <code>command1 --param1</code>, instead of <code>command1</code> only. </p>