javayaccparser-generatorjflex

BYACCJ: How do I include line number in my error message?


This is my current error handling function:

public void yyerror(String error) {
    System.err.println("Error: "+ error);
}

This is the default error function I found on the BYACC/J homepage. I can't find any way to add the line number. My question is similar to this question. But the solution to it doesn't work here.

For my lexer I am using a JFlex file.


Solution

  • It's not that different from the bison/flex solution proposed in the question you link. At least, the principle is the same. Only the details differ.

    The key fact is that it is the scanner, not the parser, which needs to count lines, because it is the scanner which converts the input text into tokens. The parser knows nothing about the original text; it just receives a sequence of nicely-processed tokens.

    So we have to scour the documentation for JFlex to figure out how to get it to track line numbers, and then we find the following in the section on options and declarations:

    • %line

      Turns line counting on. The int member variable yyline contains the number of lines (starting with 0) from the beginning of input to the beginning of the current token.

    The JFlex manual doesn't mention that yyline is a private member variable, so in order to get at it from the parser you need to add something like the following to your JFlex file:

    %line
    {
        public int GetLine() { return yyline + 1; }
        // ...
    
    }
    

    You can then add a call to GetLine in the error function:

    public void yyerror (String error) {
      System.err.println ("Error at line " + lexer.GetLine() + ": " + error);
    }
    

    That will sometimes produce confusing error messages, because by the time yyerror is called, the parser has already requested the lookahead token, which may be on the line following the error or even separated from the error by several lines of comments. (This problem often shows up when the error is a missing statement terminator.) But it's a good start.