定义令牌以匹配任何字符串
Define token to match any string
我是 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" ...
模式<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); }
}
我是 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" ...
模式<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); }
}