2013-04-02 33 views
0

我显然是在下面的语言定义了一个错误:ANTLR语言 - 树没有创建(EOF - 语法错误)

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上。

谢谢!

+0

我认为你正试图用正则表达式创建的语法规则(以小写字母开头的规则,如'object'规则)。我不认为antlr可以处理这个问题。解析器规则拥有更简单的机制。 –

+0

我在正式网站(http://www.antlr.org/wiki/display/ANTLR4/Parser+Rules#ParserRules-Subrules)中看到了一些类似于语法(*,+,?)的正则表达式的例子。 。顺便说一句,如果你有一个想法来解决我的问题,我在听你:) – Val

+0

哇,这好像叫做EBNF,我甚至不知道它存在。很高兴知道这一点。可悲的是,虽然我无法帮助你解决你的问题。 –

回答

2

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

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

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个ALTS移除不必要ALL*前缀。

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

作为最后一个变化,我将创建一个entry规则有明确的EOF结束:

entry : object EOF; 

为了解析您的输入,拨打entry()而不是object(),以确保所有的输入变得解析。如果您需要ObjectContext对象,则可以致电EntryContext.object()

+0

感谢您的快速回答!很高兴知道这不是一个错误,但树似乎不是现在生成(之前,我有一个不同的语法产生它)..你有什么想法吗? – Val

+0

我已经增强了主题主题/内容以更好地解释我的评论。 – Val

+0

@Valentin我编辑了我的答案,提到'setBuildParseTree'。 –

1

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

尝试这样:

grammar Hello; 

parse 
: object EOF 
; 

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

NAME : '"' ~["{}]* '"'; 
OBRACE : '{'; 
CBRACE : '}'; 
OTHER : ~["{}]+ -> skip; 
+0

感谢您的回答巴特。我不知道'跳过'。顺便说一句,错误仍然在这里,在字符0的最后一行:'不匹配输入''期待NAME' .. – Val