tettra
tettra

Reputation: 3

JavaCC got Lexical error when lookahead meet end of file

Why do JavaCC always give an error on terminal with lookahead? Like on this example,

options{
    LOOKAHEAD = 2;
}

PARSER_BEGIN(GS)
    public class GS{
        public static void main(String args[]) throws ParseException {
            GS parser = new GS(System.in);
            parser.q0();
        }
    }
PARSER_END(GS)

void q0():
{}
{
    "a" q1() |
    "c" 
}

void q1():
{}
{
    "b" q0()
    | "b"
}

On q1() there're 2 options, one is to read "b" and move to q0, or read "b" and end the reading. But if I give an input "ab" it will give an error even though it have lookahead option. But if I give "(ab)*c", JavaCC accept it just fine.

Exception in thread "main" TokenMgrError: Lexical error at line 1, column 3.  Encountered: "\r" (13), after : ""

This same error always happen when the production rule is

{
    "terminal_x" non-terminal()
    | "terminal_x"
}

Is there any way to make this kind of production rule without giving an error?

I'm using JavaCC ver. 6.0_1.

thanks.

edit:

Apparently, if the production rule is in the form

{
    "terminal_x"
    | "terminal_x" non-terminal()
}

The error wont happened. But still, what cause this error?

Upvotes: 0

Views: 728

Answers (2)

Theodore Norvell
Theodore Norvell

Reputation: 16221

The problem is that your input string contains a return character that the lexer is not expecting. It has nothing to do with lookhahead; lookahead has to do with parsing, not lexing. I'd suggest putting in a rule something like this.

SKIP : { " " | "\t" | "\r" | "\n" }

Upvotes: 1

LEJ
LEJ

Reputation: 1958

The example rule you have suggested:

    {
        "terminal_x"
        | "terminal_x" non-terminal()
    }

is effectively saying "there must be "terminal_x" followed by either zero or one non-terminal()". This would be done easier by using the ? operator (zero or one) as below:

    {
        "terminal_x" (non-terminal())?
    }

This way, the lookahead is not needed as it will always look for "terminal_x" and then allow either zero or one "non-terminal()", eliminating the problem completely.

Upvotes: 0

Related Questions