JAVACC:如何总是跳过\n,除非前面有分号

JAVACC: how to skip \n always except when preceded by a semicolon

我目前正在制作一个 sql 解析器,我希望为每个新输入打印一个提示。

< 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();
 }
)+

当我输入这样的内容时会出现问题:"desc a;desc a;",换句话说,当两个查询没有被 space 分隔时。 我相信这是因为一旦状态更改为 STATE,"desc" 就不再被视为 "desc",而是被视为 "d"。 我曾想过在更改状态之前尝试保存剩余的待解析输入,但我不知道如何实现。 如果有任何帮助,我将不胜感激!!

不要从解析器切换词法状态。这几乎不是一个好主意。

如果你想忽略不跟在分号后面的换行符并且不想忽略不跟在分号后面的换行符,你可以这样做:

// 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>
}

这有糟糕的错误恢复,但这是一个开始。