我正在尝试创建我的第一个ANTLR3树语法,但我仍然遇到同样的问题。解析器的输出是:
$ echo 'foo, bar' | ./run.sh
foo bar
TreeGrammar.g: node from line 0:0 required (...)+ loop did not match anything at input 'EOF'
Exception in thread "main" java.lang.NullPointerException
at Driver.main(Driver.java:29)
输出清楚地表明,stage-1解析器产生了正确的令牌('foo'和'bar')。不知何故,stage-2树解析器拒绝解析stage-1的结果。由于代码非常基础,所以我必须对它进行一些简单,愚蠢的疏忽; - )
这是我的简单测试代码:
Grammar.g:
grammar Grammar;
options {
output = AST;
}
statement: word (','! word)* EOF!;
word: ID;
ID: ('a'..'z'|'A'..'Z')+;
WS: (' ' | '\t' | '\n' | '\r')+ { $channel = HIDDEN; } ;
TreeGrammar.g:
tree grammar TreeGrammar;
options {
tokenVocab = Grammar;
ASTLabelType = CommonTree;
output = template;
}
statement: word+;
word: ID;
Driver.java:
import java.io.*;
import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
import org.antlr.stringtemplate.*;
public class Driver {
public static void main(String[] args) throws Exception {
FileReader groupFileR = new FileReader("Template.stg" );
StringTemplateGroup templates = new StringTemplateGroup(groupFileR);
groupFileR.close();
ANTLRInputStream input = new ANTLRInputStream(System.in);
GrammarLexer lexer = new GrammarLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
GrammarParser parser = new GrammarParser(tokens);
GrammarParser.statement_return result = parser.statement();
CommonTree t = (CommonTree)result.getTree();
System.out.println(t.toStringTree());
CommonTreeNodeStream nodes = new CommonTreeNodeStream(t);
nodes.setTokenStream(tokens);
TreeGrammar walker = new TreeGrammar(nodes);
walker.setTemplateLib(templates);
walker.statement();
TreeGrammar.statement_return r2 = walker.statement();
StringTemplate output = (StringTemplate) r2.getTemplate();
System.out.println(output.toString());
}
}
答案 0 :(得分:1)
假设您的Stringtemplate组已正确形成,您的问题很可能是您走两次AST:
walker.statement();
TreeGrammar.statement_return r2 = walker.statement();
例如,您拨打walker.statement()
两次。这就是(第一个)错误告诉你的事情:
TreeGrammar.g: node from line 0:0 required (...)+ loop did not match anything at input 'EOF'
您使用walker.statement()
消费输入一次,结果节点流结束(EOF),然后再次致电walker.statement()
,它预计再次行走word+
,但是#39;只剩下EOF
。