我真的很感激,如果有人可以给我建议,或者指点教程或示例实现,任何可以帮助我在ANTLR中实现基本goto语句的东西?
感谢您的帮助
修改。问题的问题2:
说我有这种树结构:
(BLOCK (PRINT 1) (PRINT 2) (PRINT 3) (PRINT 4) )
现在,我很想知道有没有办法 选择节点(PRINT 2)和后面的所有节点 那个节点((PRINT 2)(PRINT 3)(PRINT 4))?
我问这个是因为我正在努力实施 基本的转到机制。 我有这样的印刷声明:
i=LABEL print
{interpreter.store($i.text, $print.tree);} //stores in hash table
-> print
然而$ print.tree只是忽略了以后的节点, 所以在输入中:
label: print 1
print 2
goto label
将打印121! (我想要的是无限循环1212 ...)
我也尝试过服用令牌 打印声明的地址 getTokenStartIndex()和设置 具有setTokenStartIndex的根节点 但这只是一遍又一遍地圈出了第一个节点。
我的问题是,如何在antlr中实现goto语句? 也许我的方法是错的,因为我忽略了一些东西?
我真的很感激任何帮助。
PS。更详细的,它与模式25 - 语言实现模式有关,我试图从该模式中添加示例。 另外,我在网上搜索了很多,看起来很难找到goto示例
答案 0 :(得分:3)
......任何可以帮助我在ANTLR中实现基本goto语句的东西?
请注意,实现此功能的不是ANTLR。使用ANTLR,您只需描述要解析的语言,以获取词法分析器,解析器以及可能的树木助行器。在那之后,你可以操纵树并进行评估。
这是一种可行的方法。请不要仔细查看代码。这是一个快速的黑客攻击:有一些代码重复,我正在传递包受保护的变量,而不是应该做的。该语法还要求您使用label
开始输入源,但这只是 可以解决它的一个小演示。
您需要以下文件:
Goto.g
- 组合语法文件GotoWalker.g
- 树步行者语法文件Main.java
- 主要类,包括语言的节点模型类test.goto
- 测试输入源文件antlr-3.3.jar
- ANTLR JAR(也可能是另一个3.x版本)grammar Goto;
options {
output=AST;
ASTLabelType=CommonTree;
}
tokens {
FILE;
BLOCK;
}
@members {
java.util.Map<String, CommonTree[]> labels = new java.util.HashMap<String, CommonTree[]>();
}
parse
: block EOF -> block
;
block
: ID ':' stats b=block? {labels.put($ID.text, new CommonTree[]{$stats.tree, $b.tree});} -> ^(BLOCK stats $b?)
;
stats
: stat*
;
stat
: Print Number -> ^(Print Number)
| Goto ID -> ^(Goto ID)
;
Goto : 'goto';
Print : 'print';
Number : '0'..'9'+;
ID : ('a'..'z' | 'A'..'Z')+;
Space : (' ' | '\t' | '\r' | '\n') {$channel=HIDDEN;};
tree grammar GotoWalker;
options {
tokenVocab=Goto;
ASTLabelType=CommonTree;
}
tokens {
FILE;
BLOCK;
}
@members {
java.util.Map<String, CommonTree[]> labels = new java.util.HashMap<String, CommonTree[]>();
}
walk returns [Node n]
: block {$n = $block.n;}
;
block returns [Node n]
: ^(BLOCK stats b=block?) {$n = new BlockNode($stats.n, $b.n);}
;
stats returns [Node n]
@init{List<Node> nodes = new ArrayList<Node>();}
: (stat {nodes.add($stat.n);})* {$n = new StatsNode(nodes);}
;
stat returns [Node n]
: ^(Print Number) {$n = new PrintNode($Number.text);}
| ^(Goto ID) {$n = new GotoNode($ID.text, labels);}
;
import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
import org.antlr.stringtemplate.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
GotoLexer lexer = new GotoLexer(new ANTLRFileStream("test.goto"));
GotoParser parser = new GotoParser(new CommonTokenStream(lexer));
CommonTree tree = (CommonTree)parser.parse().getTree();
GotoWalker walker = new GotoWalker(new CommonTreeNodeStream(tree));
walker.labels = parser.labels;
Node root = walker.walk();
root.eval();
}
}
interface Node {
public static final Node VOID = new Node(){public Object eval(){throw new RuntimeException("VOID.eval()");}};
public static final Node BREAK = new Node(){public Object eval(){throw new RuntimeException("VOID.eval()");}};
Object eval();
}
class BlockNode implements Node {
Node stats;
Node child;
BlockNode(Node ns, Node ch) {
stats = ns;
child = ch;
}
public Object eval() {
Object o = stats.eval();
if(o != VOID) {
return o;
}
if(child != null) {
o = child.eval();
if(o != VOID) {
return o;
}
}
return VOID;
}
}
class StatsNode implements Node {
List<Node> nodes;
StatsNode(List<Node> ns) {
nodes = ns;
}
public Object eval() {
for(Node n : nodes) {
Object o = n.eval();
if(o != VOID) {
return o;
}
}
return VOID;
}
}
class PrintNode implements Node {
String text;
PrintNode(String txt) {
text = txt;
}
public Object eval() {
System.out.println(text);
return VOID;
}
}
class GotoNode implements Node {
String label;
Map<String, CommonTree[]> labels;
GotoNode(String lbl, Map<String, CommonTree[]> lbls) {
label = lbl;
labels = lbls;
}
public Object eval() {
CommonTree[] toExecute = labels.get(label);
try {
Thread.sleep(1000L);
GotoWalker walker = new GotoWalker(new CommonTreeNodeStream(toExecute[0]));
walker.labels = this.labels;
Node root = walker.stats();
Object o = root.eval();
if(o != VOID) {
return o;
}
walker = new GotoWalker(new CommonTreeNodeStream(toExecute[1]));
walker.labels = this.labels;
root = walker.block();
o = root.eval();
if(o != VOID) {
return o;
}
} catch(Exception e) {
e.printStackTrace();
}
return BREAK;
}
}
root:
print 1
A:
print 2
B:
print 3
goto A
C:
print 4
要运行演示,请执行以下操作:
java -cp antlr-3.3.jar org.antlr.Tool Goto.g
java -cp antlr-3.3.jar org.antlr.Tool GotoWalker.g
javac -cp antlr-3.3.jar *.java
java -cp .:antlr-3.3.jar Main
或:
java -cp antlr-3.3.jar org.antlr.Tool Goto.g
java -cp antlr-3.3.jar org.antlr.Tool GotoWalker.g
javac -cp antlr-3.3.jar *.java
java -cp .;antlr-3.3.jar Main
将打印:
1
2
3
2
3
2
3
2
3
...
请注意,重复2和3,直到您手动终止应用程序。