”1+1” 语法图
programAst : INTEGER PLUS INTEGER
每个语法节点对应一个类 , 在语法解析器对应一个函数 , 扩充语法的时候会遵循这个规律。
类Ast
仅声明,表示这是语法节点类。
public class Ast {}
类ProgramAst
@Data
public class ProgramAst extends Ast{
private Integer leftValue; // 左边的数值
private Integer rightValue; // 右边的数值
public ProgramAst(Integer leftValue, Integer rightValue) {
this.leftValue = leftValue;
this.rightValue = rightValue;
}
}
语法解析器
// 语法解析器
public class Parser {
private Lexer lexer ; // 词法解析器
private Token currentToken; // 当前的词法单元
public Parser(Lexer lexer) {
this.lexer = lexer;
this.currentToken = this.lexer.getNextToken();
}
public ProgramAst programAst(){ // 程序节点
// programAst : INTEGER PLUS INTEGER
Token left = this.currentToken;
this.eat(TokenType.INTEGER);
this.eat(TokenType.PLUS);
Token right = this.currentToken;
this.eat(TokenType.INTEGER);
return new ProgramAst((Integer)left.getValue() , (Integer)right.getValue());
}
public void eat(TokenType tokenType){ // 确认当前的词性是否正确
if(tokenType == this.currentToken.getType()){
this.currentToken = this.lexer.getNextToken();
}else{
this.error("语法错误");
}
}
public void error(String msg){ // 报错函数
throw new RuntimeException(msg);
}
public Ast parse(){ // 获取语法树
return this.programAst();
}
}
单元测试
private static void testParser() {
Lexer lexer = new Lexer("1+1");
Parser parser = new Parser(lexer);
Ast ast = parser.parse();
System.out.println(ast);
}
执行结果:
ProgramAst(leftValue=1, rightValue=1)