我正在尝试创建简单的翻译器,例如:
aaa | bbb | ccc
到
1 : aaa
2 : bbb
c : ccc
这是语法test01.g:
grammar test01;
options {
output=AST;
}
@members{
int N;
}
test
@init{
N = 0;
}:
id ('|' id)* -> id (BR id)*;
id : {N++;} ID -> {new CommonTree(new CommonToken(ID, Integer.toString(N) + " : " + $ID.text))};
ID : ('a'..'z')+;
BR : '\n';
WS : ' '{$channel=HIDDEN;};
译者来源FooTest.java:
import org.antlr.runtime.*;
class FooTest {
public static void main(String[] args) throws Exception {
String text = "aaa | bbb | ccc";
System.out.println("parsing: "+text);
ANTLRStringStream in = new ANTLRStringStream(text);
test01Lexer lexer = new test01Lexer(in);
CommonTokenStream tokens = new TokenRewriteStream(lexer);
test01Parser parser = new test01Parser(tokens);
parser.test();
System.out.println("Result: "+tokens.toString());
}
}
当我运行它时,我希望得到类似的东西:
parsing: aaa | bbb | ccc
Result:
1 : aaa
2 : bbb
3 : ccc
但我明白了:
parsing: aaa | bbb | ccc
Result: aaa | bbb | ccc
文字似乎未经修改。
如何修改源代码?
答案 0 :(得分:1)
您只需打印 flat 令牌列表:
CommonTokenStream tokens = new TokenRewriteStream(lexer);
// ...
System.out.println("Result: "+tokens.toString());
如果您将FooTest
课程调整为:
import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
class FooTest {
public static void main(String[] args) throws Exception {
String text = "aaa | bbb | ccc";
System.out.println("parsing: "+text);
ANTLRStringStream in = new ANTLRStringStream(text);
test01Lexer lexer = new test01Lexer(in);
CommonTokenStream tokens = new TokenRewriteStream(lexer);
test01Parser parser = new test01Parser(tokens);
CommonTree root = (CommonTree)parser.test().getTree();
for(int i = 0; i < root.getChildCount(); i++) {
CommonTree child = (CommonTree)root.getChild(i);
System.out.println("root.children[" + i + "] = " + child);
}
}
}
以下内容将打印到控制台:
parsing: aaa | bbb | ccc
root.children[0] = 1 : aaa
root.children[1] = BR
root.children[2] = 2 : bbb
root.children[3] = BR
root.children[4] = 3 : ccc
请注意,您不需要在解析器类中放置全局变量。规则还处理变量(它们的本地)。这是首选:
grammar test01;
options {
output=AST;
}
test:
id ('|' id)* -> id (BR id)*;
id
@init{
int N = 0;
}
: {N++;} ID -> {new CommonTree(new CommonToken(ID, Integer.toString(N) + " : " + $ID.text))}
;
// other rules