Ast.java 12.11 KiB
package frontend.syntax;
import frontend.lexer.Token;
import frontend.lexer.TokenType;
import java.util.ArrayList;
/**
 * 所有的语法树节点
 * 为简化编译器实现难度, 对文法进行了改写(不影响语义)
public class Ast {
    public ArrayList<CompUnit> units;
    // CompUnit -> Decl | FuncDef
    public interface CompUnit {
    // Decl -> ['const'] 'int' Def {',' Def} ';'
    public static class Decl implements CompUnit, BlockItem {
        public boolean constant;
        public Token bType;
        public ArrayList<Def> defs;
        public Decl(boolean constant, Token bType, ArrayList<Def> defs) {
            assert bType != null;
            assert defs != null;
            this.constant = constant;
            this.bType = bType;
            this.defs = defs;
        public boolean isConstant() {
            return this.constant;
        public Token getBType() {
            return bType;
        public ArrayList<Def> getDefs() {
            return defs;
    // Def -> Ident {'[' Exp ']'} ['=' Init]
    public static class Def {
        public TokenType bType;
        public Token ident;
        public ArrayList<Exp> indexes;
        public Init init;
        public Def(TokenType bType, Token ident, ArrayList<Exp> indexes, Init init) {
            assert bType != null;
            assert ident != null;
            assert indexes != null;
            // assert init != null;
            this.bType = bType;
            this.ident = ident;
            this.indexes = indexes;
            this.init = init;
        public Token getIdent() {
            return this.ident;
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
public ArrayList<Exp> getIndexes() { return this.indexes; } public Init getInit() { return this.init; } } // Init -> Exp | InitArray public interface Init { } // InitArray -> '{' [ Init { ',' Init } ] '}' public static class InitArray implements Init { public ArrayList<Init> init; public int nowIdx = 0; public InitArray(ArrayList<Init> init) { assert init != null; this.init = init; } public Init getNowInit() { // if(nowIdx > this.init.size()){ // throw new AssertionError("fuck idx wrong"); // } // assert nowIdx < this.init.size(); return this.init.get(nowIdx); } public boolean hasInit(int count){ return nowIdx < this.init.size(); } } // FuncDef -> FuncType Ident '(' [FuncFParams] ')' Block // FuncFParams -> FuncFParam {',' FuncFParam} public static class FuncDef implements CompUnit { public Token type; // FuncType public Token ident; // name public ArrayList<FuncFParam> fParams; public Block body; public FuncDef(Token type, Token ident, ArrayList<FuncFParam> fParams, Block body) { assert type != null; assert ident != null; assert fParams != null; assert body != null; this.type = type; this.ident = ident; this.fParams = fParams; this.body = body; } public Token getType() { return this.type; } public Token getIdent() { return this.ident; } public ArrayList<FuncFParam> getFParams() { return this.fParams; } public Block getBody() { return this.body;