0
votes
iteration_stmt : WHILE              {$$ = LabelSeed; LabelSeed++;
                                     fprintf(fp, "While%i:\n", $$);
                                    }
                 '(' expression ')' {fprintf(fp, "cmp %s, 1\n", regToString($<n>3));
                                     fprintf(fp, "jne EndWhile%i\n", $$);
                                     NextReg--;
                                    }
                 statement          {fprintf(fp, "jmp While%i\n", $$);
                                     fprintf(fp, "EndWhile%i:\n", $$);
                                    }
                ;

I'm trying to use iteration_stmt's semantic value to keep track of the LabelSeed value, however it's value doesn't stay the same through out the other 2 actions. For example, in one case my output is:

While0:
...
jne EndWhile1
...
jmp While0
EndWhile0:

in another its:

While2:
...
jne EndWhile2
...
jmp While0
EndWhile0:

The integer should stay constant. I cant think of any reason the semantic value would change. Can anyone point me in the right direction?

1

1 Answers

0
votes

The semantic value of iteration_stmt will not be set until the entire rule is reduced, at which point $$ can be used to refer to it in the action code. Your use of $$ in the action code segments actually refers to implicit partially completed parts of the rule; only in the action for the ending statement non-terminal will $$ refer to iteration_stmt.

This is because internally yacc/bison implements rules with mid-rule actions as a cascade of rules of regular form, with actions at the end only.

So, try this:

iteration_stmt : WHILE              {$$ = LabelSeed; LabelSeed++;
                                     fprintf(fp, "While%i:\n", $$);
                                    }
                 '(' expression ')' {fprintf(fp, "cmp %s, 1\n", regToString($<n>3));
                                     fprintf(fp, "jne EndWhile%i\n", $1);
                                     NextReg--;
                                    }
                 statement          {fprintf(fp, "jmp While%i\n", $1);
                                     fprintf(fp, "EndWhile%i:\n", $1);
                                    }
                ; 

Where the first $$ loads a semantic value for the WHILE token, which the other actions can reference.