定义令牌以匹配任何字符串

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