每次使用javacc工具解析赋值语句时,为什么我的语法检查失败?

时间:2015-04-09 06:40:41

标签: java compiler-construction io javacc

我已经创建了一个AssignStatement类,我正在尝试使用javacc传递字符串

赋值语句的格式为:a=b+c*d

这是源代码

PARSER_BEGIN(AssignStatement)

public class AssignStatement
{      

  public static void main(String s[])
  {
   try
     {
       AssignStatement as=new AssignStatement(System.in);
       as.StartSymbol();
       System.out.println("Syntax checking successfully");
     }

  catch(Throwable e)
     {
      System.out.println("Syntex checking failed"+e.getMessage());
     }
  }
}

PARSER_END(AssignStatement)

   SKIP: {"" | "\t" | "\n" | "\r" }
   TOKEN:{ "(" | ")" | "+" | "*" | ":="| <NUM: (["0"-"9"])+> | <ID:(["0"-"9"])+>
         }

   void StartSymbol(): {}
  { 
    (AStmt())*<EOF>
  }

  void AStmt(): {}
 { 
  LOOKAHEAD(2) <ID> "=" AStmt() 
  | Term() ("+" Term())*
 }

  void Term(): {}
 {
  Factor() ("*" Factor())*
 } 

  void Factor(): {}
 {
    <NUM> 
  | <ID> 
  | "(" AStmt() ")"
 }

我完成java AssignStatement

后得到的输出
"a=10+20*30" or a=10+20*30
  

语法检查失败错误:在第1行第1列重复出现空字符串匹配导致无限循环失效。

从我的角度来看,可能有两种可能性

  1. 我正在接受用户错误的输入[在这种情况下请建议以及如何从文件中获取输入

  2. 我的语法错了。请建议

  3. 如果有人可以指导吗?

1 个答案:

答案 0 :(得分:2)

问题在于

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

这表示你想要跳过任何0长度的字符串。问题是,找到这样一个令牌后,词法分析器会从输入中删除0个字符,然后,当然,它会找到相同的0长度令牌,依此类推 ad infinitum

也许你的意思是

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

现在,在输入“a = 10 + 20 * 30”时,没有正则表达式匹配,你将得到一个TokenManagerError。

匹配空字符串有其(罕见)用途。这不是其中之一。

第二个问题是规则

TOKEN:{ ... <NUM: (["0"-"9"])+> | <ID:(["0"-"9"])+> }

由于ID的定义与NUM的定义相同,因此永远不会成功。也许你想要像

这样的东西
TOKEN:{ ... <NUM: (["0"-"9"])+> | <ID:(["a"-"z"])+> }

如果你这样做,你将不会在输入“a = 10 + 20 * 30”上得到TokenManagerError。