abstract-syntax-tree - 如何将 LR(1) Parse 转换为抽象语法树?

标签 abstract-syntax-tree lr-grammar semantic-analysis lr1 concrete-syntax-tree

我已经编写了一个表驱动的 LR(1) 解析器,它工作得很好,但是在将解析转换为语法树/抽象语法树的阶段,我有点脱节。这是一个我非常热衷的项目,但我真的陷入了死胡同。提前谢谢你的帮助。

编辑:我的解析器也只使用一个二维数组和一个 Action 对象,告诉它下一步要去哪里,或者是否减少去哪里以及要弹出多少个项目。我注意到很多人使用访客模式。我不确定他们如何知道要制作什么类型的节点。

这是上下文的下推自动机

 while (lexer.hasNext() || parseStack.size() > 0) {
        Action topOfStack = parseStack.peek();
        token = parseStack.size() > 0 ? lexer.nextToken() : new Token(TokenType.EOF, "EOF");
        topOfStack.setToken(token);

        int row = topOfStack.getTransitionIndex();
        int column = getTerminalIndex(token.getLexeme());

        column = token.getType() == TokenType.IDENTIFIER
                && !terminalsContain(token.getLexeme()) ? 0 : column;

        Action action = actionTable[row][column];

        if (action instanceof Accept) {
            System.out.println("valid parse!!!!!!");
        } else if (action instanceof Reduction) {
            Reduction reduction = (Reduction) action;

            popStack(parseStack, reduction.getNumberOfItemsToPop());
            column = reduction.getTransitionIndex();
            row = parseStack.peek().getTransitionIndex();

            parseStack.push(new Action(gotoTable[row][column]));
            lexer.backupTokenStream();
        } else if (action != null) {
            parseStack.push(actionTable[row][column]);
        } else {
            System.out.println("Parse error");
            System.out.println("On token: " + token.getLexeme());
            break;
        }

最佳答案

LR解析过程中的每个约简都对应于解析树中的一个内部节点。被归约的规则是内部 AST 节点,从堆栈中弹出的项目对应于该内部节点的子节点。 goto 推送的项目对应于内部节点,而 shift 操作推送的项目对应于 AST 的叶子(标记)。

将所有这些放在一起,您可以通过每次进行归约时创建一个新的内部节点并将所有内容适本地连接在一起来轻松构建 AST。

关于abstract-syntax-tree - 如何将 LR(1) Parse 转换为抽象语法树?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30445511/

相关文章:

parsing - LL(1)、LR(1)、LR(0)、LALR(1) 语法示例?

stanford-nlp - 斯坦福 NLP 解析器是否有语义角色标记方法?

python - 如何找出函数(的源代码)是否包含循环?

c++ - 使用 libclang 检查通用属性

parsing - 是否有处理 S/R 和 R/R 冲突的 LR(0) 解析算法?

c - 创建 AST 后进行语义检查

parsing - 综合和继承属性

clang - 向 Clang 的 AST 添加节点

ANTLR 的 Java 树解析器输出