章节6:计算”1+1”语法解析

35 阅读1分钟

”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)