0

我在以下语言定义中显然有一个错误:

grammar Hello;


object  :
ALL* NAME ALL* '{' 
    (ALL* | (ALL* NAME ALL* NAME)* | (ALL* object)*)*
'}' ALL*;

ALL     :
(~('{' | '}' | '"'))+ -> skip;      // All but braces and double quotes

NAME    :
'"' ALL* '"';


当我尝试读取文件或直接添加内容(使用run.bat Hello object -gui)时,解析器给我一个语法错误mismatched input '<EOF>' expecting NAME. 而且我只有一个带有单个节点的树:'object'。


这是Java源代码:

public static void main(String[] args) throws Exception {
    HelloLexer lexer = new HelloLexer(new ANTLRFileStream("gamemodes.txt"));
    TokenStream tokenStream = new CommonTokenStream(lexer);
    HelloParser parser = new HelloParser(tokenStream);

    System.out.println(lexer.getAllTokens().size());

    parser.setBuildParseTree(true);

    // Tree Creation
    RuleContext tree = parser.object();
    tree.inspect(parser);
}


最后,文件结构(在任何地方都有一些空格/字符(没有大括号和双引号)):

...
"objName"
{
    ...
    "innerObjName1"
    {
        "firstProperty"  "firstResult"
        ...
        "secondProp"     ""
    }

    "innerObjName2"
    {
        "firstProperty"  "firstResult"
        "secondProp"     ""
    }
}
...


注意:我在 Windows 上。

谢谢 !

4

2 回答 2

2

reportAttemptingFullContext不是错误。它只是让您知道 ANTLR 4 正在使用其内部实现部分,该部分使用完整的解析上下文来确保准确性。包含该消息是因为完整上下文算法比它首先尝试的 SLL 算法慢一点。

编辑:如果您使用的是非标准发行版,您可能需要指定以下选项以确保构建解析树。此选项在官方发行版中默认为 true。

parser.setBuildParseTree(true);

编辑 2:涵盖语法问题。

这是object原始语法中的规则,只有格式更改。

object // intermediate form 1
    :   ALL* NAME ALL* '{' 
        (   ALL*
        |   (ALL* NAME ALL* NAME)*
        |   (ALL* object)*
        )*
        '}' ALL*
    ;

这个规则是高度模糊的。作为一个简单的示例,请注意以下修改后的语法实际上将匹配相同的输入。

object // intermediate form 2
    :   ALL* NAME ALL* '{' 
        (   ALL
        |   ALL* NAME ALL* NAME
        |   ALL* object
        )*
        '}' ALL*
    ;

另一个简化从 2 个 alt 中删除了不必要的ALL*前缀。

object // final form
    :   ALL* NAME ALL* '{' 
        (   ALL
        |   NAME ALL* NAME
        |   object
        )*
        '}' ALL*
    ;

作为最后的更改,我将创建一个entry以显式结尾的规则EOF

entry : object EOF;

要解析您的输入,请调用entry()而不是object()确保解析您的所有输入。如果您需要该ObjectContext对象,可以通过调用EntryContext.object().

于 2013-04-02T20:03:10.920 回答
1

当您skip使用词法分析器规则时,您不得在解析器规则中使用它。

尝试这样的事情:

grammar Hello;

parse
 : object EOF
 ;

object
 : NAME (OBRACE object+ CBRACE | NAME)
 ;

NAME   : '"' ~["{}]* '"';
OBRACE : '{';
CBRACE : '}';
OTHER  : ~["{}]+ -> skip;
于 2013-04-05T12:15:04.123 回答