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

时间:2017-10-28 14:17:54

标签: javacc

我是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" ...

1 个答案:

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