0

I am working on a yacc file to parse a given file and convert it to an equivalent c++ file. I have created the following grammar based on the provided syntax diagrams:

program:    PROGRAMnumber id 'is' comp_stmt
            ;

comp_stmt:    BEGINnumber statement symbol ENDnumber
              ;

statement:    statement SEMInumber statement 
              | id EQnumber expression
              | PRINTnumber expression
              | declaration
              ;

declaration:    VARnumber id
                ;

expression:    term
               ;

term:    term as_op term
         | MINUSnumber term
         | factor
         ;

factor:    factor md_op factor
           | ICONSTnumber
           | id
           | RPARENnumber expression LPARENnumber
           ;

as_op:    PLUSnumber
          | MINUSnumber
          ;

md_op:    TIMESnumber
          | DIVnumber
          ;

symbol:    SEMInumber
           | COMMAnumber
           ;

id:    IDnumber
       | id symbol id
       ;

The only issue I have remaining is that I am receiving this error when trying to compile with yacc.

conflicts: 14 shift/reduce
calc.y:103.17-111.41: warning: rule useless in parser due to conflicts: declaration: VARnumber id

I have resolved the only other conflict I have encountered, but I am not sure what the resolution for this conflict is. The line it should match is of the format

var a, b, c, d;

or

var a;
neomang
  • 117
  • 3
  • 10
  • Please fix your formatting. Also, single quotes are for single-character tokens; with bison, you can use `"var"`, but you still need a `%token` declaration to have a symbolic value you can return from your scanner. – rici Mar 05 '16 at 03:10
  • I fixed that issue in my last edit. There was a token set up for var, I missed it initially, but even after replacing it, the error remains. What other issues do you see with my formatting, so I can fix them? – neomang Mar 05 '16 at 03:13
  • 2
    Are you really using token names like `COMMAnumber`? That verges on the unreadable... I assumed they were missing whitespace. Do you have `%left` declarations? – rici Mar 05 '16 at 03:17
  • I'm using a lex file provided for the project. That's just what I was given to work with. – neomang Mar 05 '16 at 03:17

1 Answers1

4

All of your productions intended to derive lists are ambiguous and therefore generate reduce/reduce conflicts. For example:

 id: id symbol id

Will be clearly ambiguous when there are three identifiers: are the first two to be reduced first, or the last two? The usual list idiom is left-recursion:

id_list: id | id_list `,` id

For most languages, that would not be correct for statements, which are terminated with semi-colons, not separated by them, but that model would work for a comma-separated list of identifiers, or for a left-associative sequence of addition operators.

For statements, you probably want something more like:

statement_list: | statement_list statement ';' 

Speaking of symbol, do you really believe that , and ; have the same syntactic function? That seems unlikely, since you write var a, b, c, d; and not, for example, var a; b, c; d,.

The "useless rule" warning produced by bison is exactly because your grammar allows ids to be separated with semicolons. When the parser sees "var" ID with ; as lookahead, it first reduces ID to id and then needs to decide whether to reduce var id to declaration or to shift the ; in order to later reduce it to symbol and then proceed with the reduction of id symbol id. In the absence of precedence rules, bison always resolves shift/reduce conflicts in favour of shifting, so that is what it does in this case. But the result is that it is never possible to reduce "var" id to declaration, making the production useless as the result of a shift-reduce conflict resolution, which is more or less what the warning says.

rici
  • 234,347
  • 28
  • 237
  • 341
  • My apologies. I actually resolved the issue with the statement conflict before posting this but forgot to update it in the code block. I have fixed this, but your solution seems more elegant so I may integrate that method instead. However, this doesn't address the remaining conflict I am encountering. I am more concerned at the moment with the conflict listed in the original question. – neomang Mar 05 '16 at 03:47
  • @neomang: I'm pretty sure it is a consequence of the `id` ambiguity. Don't make the assumption that conflicts are local to the rule where you observe the consequence. – rici Mar 05 '16 at 03:57
  • @neomang: In fact, it was the `id: id symbol id` rule which was responsible. Updated the answer with an explanation. – rici Mar 05 '16 at 18:46