Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bison : Line number included in the error messages

OK, so I suppose my question is quite self-explanatory.

I'm currently building a parser in Bison, and I want to make error reporting somewhat better.

Currently, I've set %define parse.error verbose (which actually gives messages like syntax error, unexpected ***********************, expecting ********************.

All I want is to add some more information in the error messages, e.g. line number (in input/file/etc)

My current yyerror (well nothing... unusual... lol) :

void yyerror(const char *str)
{
    fprintf(stderr,"\x1B[35mInterpreter : \x1B[37m%s\n",str);
}

P.S.

  • I've gone through the latest Bison documentation, but I seem quite lost...
  • I've also had a look into the %locations directive, which most likely is very close to what I need - however, I still found no complete working example and I'm not sure how this is to be used.
like image 379
Dr.Kameleon Avatar asked Mar 14 '14 14:03

Dr.Kameleon


People also ask

What is a Bison error?

error. A token name reserved for error recovery. This token may be used in grammar rules so as to allow the Bison parser to recognize an error in the grammar without halting the process.

What is GNU bison used for?

Bison is a general-purpose parser generator that converts an annotated context-free grammar into a deterministic LR or generalized LR (GLR) parser employing LALR (1) parser tables. As an experimental feature, Bison can also generate IELR (1) or canonical LR(1) parser tables.


2 Answers

So, here I'm a with a step-by-step solution :

  • We add the %locations directive in our grammar file (between %} and the first %%)
  • We make sure that our lexer file contains an include for our parser (e.g. #include "mygrammar.tab.h"), at the top
  • We add the %option yylineno option in our lexer file (between %} and the first %%)

And now, in our yyerror function (which will supposedly be in our lexer file), we may freely use this... yylineno (= current line in file being processed) :

void yyerror(const char *str)
{
    fprintf(stderr,"Error | Line: %d\n%s\n",yylineno,str);
}

Yep. Simple as that! :-)

like image 131
Dr.Kameleon Avatar answered Sep 28 '22 16:09

Dr.Kameleon


Whats worked for me was adding extern int yylineno in .ypp file:

/* parser.ypp */
%{
    extern int yylineno;
%}

/* scanner.lex */
...
%option yylineno
like image 39
Dennis Vash Avatar answered Sep 28 '22 16:09

Dennis Vash