0

I am currently moving a fun-project of mine over to bison/flex as parser and have trouble solving a reduce/reduce conflict:

// https://github.com/X39/yaoosl/blob/master/code-gen/yaoosl.y#L761-L766
ifthen: YST_IF YST_ROUNDO expression code_ifstart YST_ROUNDC codebody code_ifendnoelse
        | YST_IF YST_ROUNDO expression code_ifstart YST_ROUNDC ifthen_clsd YST_ELSE code_ifelse ifthen code_ifendelse
        ;
ifthen_clsd: codebody
           | YST_IF YST_ROUNDO expression code_ifstart YST_ROUNDC ifthen_clsd code_ifelse YST_ELSE ifthen_clsd code_ifendelse
           ;

Note: stuff prefixed with code_ are the mid-actions

Could somebody explain to me how to solve this properly and why the "go-to" solution is either wrong or did not worked? Thanks, X39

X39
  • 789
  • 6
  • 22

1 Answers1

1

Since the two rules are identical up to the code_ifelse (and assuming code_ifelse is an empty rule, like an in-rule action), it can't tell whether to reduce code_ifelse before or after the YST_ELSE. You might be able to fix it by making the two rules consistent with the order of code_ifelse and YST_ELSE.

Some rules-of-thumb for grammars:

  • Don't use symblic names for single char tokens like '(' and ')' -- it just obfuscates things and makes the grammar hard to read and understand.
  • Don't use in-rule actions unless absolutely necessary -- it's better to create a single token rule with an end-rule action that does what you need.
Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
  • Problem i have is that inside the `code_` sections essential setup code for the if-else is emited into some byte array (jump & skip instructions) and removing them is not possible without crafting even more code surrounding them. – X39 Apr 23 '20 at 22:11
  • If you can put that code on a rule `else: YST_ELSE { code }` as an end-rule action, its less likely to lead to conflicts. As such, it will still run before any code related to statements after then else token. – Chris Dodd Apr 23 '20 at 22:50