我编写了一个表驱动的LR(1)解析器,它运行得非常好但是我在将语法树/抽象语法树中的语法转换的阶段有一点脱节。这是一个我非常热衷的项目,但我真的只是在这里走到了尽头。提前谢谢你的帮助。
编辑:我的解析器也只使用了一个二维数组和一个操作对象,它告诉它下一步该去哪里,或者它是一个减少的地方,以及要弹出多少项。我注意到很多人都使用访客模式。我不知道他们怎么知道要做什么类型的节点。
以下是上下文的下推自动机
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;
}
答案 0 :(得分:3)
LR解析过程中的每个减少对应于解析树中的内部节点。减少的规则是内部AST节点,从堆栈弹出的项对应于该内部节点的子节点。为goto推送的项目对应于内部节点,而由shift操作推送的项目对应于AST的叶子(令牌)。
将所有这些放在一起,您可以通过在每次进行减少时创建一个新的内部节点并将所有内容连接在一起来轻松构建AST。