我是javacc的新手。我正在尝试定义一个可以匹配任何字符串的令牌。我正在遵循不起作用的正则表达式语法<ANY: (~[])+>
。我想要实现一些非常简单的事情,定义一个具有以下BNF的表达式:
<exp> ::= "path(" <string> "," <number> ")"
我当前的.jj文件如下,有关如何解析字符串的任何帮助:
options
{
}
PARSER_BEGIN(SimpleAdd)
package SimpleAddTest;
public class SimpleAdd
{
}
PARSER_END(SimpleAdd)
SKIP :
{
" "
| "\r"
| "\t"
| "\n"
}
TOKEN:
{
< NUMBER: (["0"-"9"])+ > |
<PATH: "path"> |
<RPAR: "("> |
<LPAR: ")"> |
<QUOTE: "'"> |
<COMMA: ","> |
<ANY: (~[])+>
}
int expr():
{
String leftValue ;
int rightValue ;
}
{
<PATH> <RPAR> <QUOTE> leftValue = str() <QUOTE> <COMMA> rightValue = num() <LPAR>
{ return 0; }
}
String str():
{
Token t;
}
{
t = <ANY> { return t.toString(); }
}
int num():
{
Token t;
}
{
t = <NUMBER> { return Integer.parseInt(t.toString()); }
}
我使用上述javacc文件得到的错误是:
Exception in thread "main" SimpleAddTest.ParseException: Encountered " <ANY> "path(\'5\',1) "" at line 1, column 1.
Was expecting:
"path" ...
答案 0 :(得分:2)
模式<ANY: (~[])+>
确实匹配任何非空字符串。问题是这不是你真正想要的。如果您有一个规则<ANY: (~[])+>
,它将匹配整个文件,除非该文件为空。在大多数情况下,由于匹配规则最长,整个文件将被解析为[ANY, EOF]
。这真的是你想要的吗?可能不是。
所以我要猜你真正想要的东西。我猜你想要任何不包含双引号字符的字符串。也许还有其他限制,例如没有非打印字符。如果前面有反斜杠,也许你想允许双引号。谁知道?根据需要进行调整。
这是你能做的。首先,用
替换标记定义TOKEN:
{
< NUMBER: (["0"-"9"])+ > |
<PATH: "path"> |
<RPAR: "("> |
<LPAR: ")"> |
<COMMA: ","> |
<STRING: "\"" (~["\""])* "\"" >
}
然后将你的语法改为
int expr():
{
String leftValue ;
int rightValue ;
}
{
<PATH> <RPAR> leftValue=str() <COMMA> rightValue = num() <LPAR>
{ return 0; }
}
String str():
{
Token t;
int len ;
}
{
t = <String>
{ len = t.image.length() ; }
{ return t.image.substring(1,len-1); }
}