0

my bison grammar met an error:

parser.yy:

%union {
  Ast *ast;
  char *str;
  int tok;
}

%token <tok> NEWLINE SEMICOLON
%type <ast> Semi

%%

Semi: NEWLINE { $$ = new Ast($1); }
    | SEMICOLON { $$ = new Ast($1); }
    ;

Statements: Statement
          | Statement Semi Statements
          ;

Statement: ...
         ;

%% 

It gives error message:

Parser.yy:xxx.x-x: error: rule given for Semi, which is a token

Is there a way to implement this ?

Or I have to write it like this: ?

Statements: Statement
          | Statement NEWLINE Statements
          | Statement SEMICOLON Statements
          ;
linrongbin
  • 2,967
  • 6
  • 31
  • 59
  • Use another name for `Semi`? – Paul Ogilvie Aug 20 '20 at 08:58
  • it's just a rule naming duplicate issue ? – linrongbin Aug 20 '20 at 09:13
  • 2
    If I remove the `...` from your code, it compiles without errors - just some warnings about useless rules. If I make `Statements` the start rule, those warnings disappear as well. Either way I can not reproduce the error message you posted. Please provide a [MCVE]. – sepp2k Aug 20 '20 at 10:12

1 Answers1

0

Semi is a token. It doesn't need define rule to return. Just use it.

  • Just baseuse its type – Zeyu Li May 17 '22 at 07:15
  • According to the declarations in OP's code, `SEMICOLON` is a token and `Semi` is a non-terminal. If OP removes the definition of `SEMICOLON` from the posted code and keeps everything else as-is, that's only going to lead to an error about using an undefined non-terminal. More over, judging by the name (which isn't all caps) and its definition, it seems clear that `Semi` is also not *intended* to be a token, but a non-terminal that can match one of two tokens (which it is). – sepp2k May 17 '22 at 10:02