前面已经在语法分析过程中实现的语法分析树的构造
接下来,遍历语法分析树,并且加入动作
1.需要解决的问题
1)怎么加入动作,怎么方便的动态加入,简单表达
一个产生式样式如:E -> E + T,用符号作为分割符,0E1+2T3,4个位置加入Translator
动作的接口实现
public interface Translator { void translate(Node pre, Node next); }
例:语义规则E.val = E.val + T.val ,在所有节点后执行语义动作,则如下实现
Production.of("E -> E + T").addTranslator(3, (pre, next) -> { Node e = pre.getParent().getChildren().get(0); Node t = pre.getParent().getChildren().get(2); pre.getParent().setVal((Integer)e.getVal() + (Integer)t.getVal()); })
2)在遍历的时候执行Translator
public void translateWithThree(Node root) { if (root.getChildren() == null || root.getChildren().isEmpty()) { return; } Node pre = null; // E -> 0 E 1 + 2 T 3 节点加上可能插入的动作总共7个 // 0 1 2 3 4 5 6 int end = root.getChildren().size() * 2; for (int i=0; i<=end; i++) { if (i % 2 == 0) {// 动作 int t = i / 2; Node next = null; if (t < root.getChildren().size()) { next = root.getChildren().get(t); } Translator translator = root.getProduction().getTranslator(t); if (translator != null) { translator.translate(pre, next); } } else {// 节点 int nodeIdx = (i - 1) / 2; Node child = root.getChildren().get(nodeIdx); translateWithThree(child); pre = child; } } }
3)翻译一下计算器
语法:
S' -> L L -> E E -> E + T E -> T T -> T * F F -> ( E ) F -> d
加入语义动作
Production.of("E -> E + T").addTranslator(3, (pre, next) -> { Node e = pre.getParent().getChildren().get(0); Node t = pre.getParent().getChildren().get(2); pre.getParent().setVal((Integer)e.getVal() + (Integer)t.getVal()); })
Production.of("T -> T * F").addTranslator(3, (pre, next) -> { Node e = pre.getParent().getChildren().get(0); Node t = pre.getParent().getChildren().get(2); pre.getParent().setVal((Integer)e.getVal() * (Integer)t.getVal()); })
其他都是赋值操作,将子节点赋值到父节点
执行,translateWithThree方法,参数
3 * 5 + 4
正确输出结果
19