0

In lex/flex, one can match multiple patterns to a token using normal regex rules, but what is the equivalent on the yacc/bison side?

In my code I have two possible grammars for a single task:

IF expression THEN number
IF expression GOTO number

It seemed obvious...

|
IF expression THEN number
|
IF expression GOTO number
{ ... guts of the handler go here... }

But bison complains type clash on default action: <statement> != <>. Some googling turned up that if you don't have an action for a given entry it assumes the action is { $$ = $1; };, which is why you get this error. Fair enough.

It would seem this is a common sort of task, so I looked in a half dozen examples of little parsers on github and it seems it is not so common after all.

So what is the correct syntax here?

Maury Markowitz
  • 9,082
  • 11
  • 46
  • 98

1 Answers1

1

In yacc/bison syntax, each alternative has its own action, which is almost always what you want. There is no syntax for grouping several alternatives. So you would need to duplicate the action:

 if: IF expression THEN number { do_Something ($2, $4); }
   | IF expression GOTO number { do_Something ($2, $4); }

If you don't like duplicate actions, group your semantically identical tokens:

 then: THEN | GOTO
 if:   IF expression then number { do_Something ($2, $4); }
rici
  • 234,347
  • 28
  • 237
  • 341
  • It seems surprising this is not possible, but such is life. Unfortunately, the second doesn't work because `IF 1=1 THEN PRINT...`. Bummer. – Maury Markowitz Dec 17 '20 at 20:02
  • @maury: I bet you didn't try. You actually could add the production `IF expression THEN statement` as long as `statement` can't produce `number` – rici Dec 17 '20 at 20:05
  • (That's because LR parsing allows productions to be ambiguous until a reduction is necessary) – rici Dec 17 '20 at 20:11
  • statement did allow number, but I'm rearranging it so it won't – Maury Markowitz Dec 18 '20 at 16:33