我编写了一个表驱动的 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;
}