Reputation: 47
I am currently making a sql parser and I wish to print a prompt for each new input.
< STATE >
TOKEN:
{
< ENTER : "\n" > : DEFAULT
| < ELSE: ~[] > : DEFAULT
}
<DEFAULT>
TOKEN:
{ <DESC: "desc">
|....
}
[...]
(
q = query()
< SEMICOLON >
{
token_source.SwitchTo(STATE) ;
if(getToken(1).image == "\n")
{
printMessage(q);
getNextToken();
System.out.print("INPUT > ");
}
else
printMessage(q);
token_source.SwitchTo(DEFAULT);
if(getToken(0).image == ";") getNextToken();
}
)+
The problem happens when I enter something like this: "desc a;desc a;", in other words, when two queries are not separated by a space. I believe this is because as soon as the state is changed to STATE, the "desc" is no longer taken as "desc" but rather as "d". I have thought of trying to save the remaining to-parse input before changing the state, but I don't know how to implement that. I would really appreciate any help!!
Upvotes: 0
Views: 275
Reputation: 16221
Don't switch lexical states from the parser. It's almost never a good idea.
If you want to ignore newlines that don't follow semicolons and not ignore newlines that don't follow semicolons, you could do something like this:
// Skip white space, but stay in the same state so a newline follows white space
// that follows a semicolon, it will be treated as a token.
< * > SKIP: { " " | "\t" | "\f" }
// Skip newlines that don't follow semicolons
< DEFAULT > SKIP: { "\n" | "\r" }
// Other newlines result in ENTER tokens
< AFTER_SEMICOLON > TOKEN: {
< ENTER : "\n" | "\r" > : DEFAULT }
<*> TOKEN : {
< SEMI_COLON : ";" > : AFTER_SEMICOLON
|
< DESC : "desc" > : DEFAULT
|
<ID : (["a"-"z","A"-"Z"])+ > : DEFAULT
//etc etc
|
<UNEXPECTED_CHARACTER : ~[] > : DEFAULT
}
void many_lines() :
{}
{
{ System.out.print( ">" ) ; }
(
one_line()
many_lines()
|
<EOF>
)
}
void one_line() :
{}
{
expr() <SEMI_COLON>
(
<ENTER>
|
one_line()
)
}
void expr() :
{}
{
<DESC> <ID>
}
This has lousy error recovery, but it's a start.
Upvotes: 1