Exp Parse(void) { Lexical L; Symbol ID; Exp E;//, E0, E1; SP = Stack; L = Scan(); LHS: if (L == SymT) { ID = LastID; L = Scan(); if (L == EqualT) PUSH(EQU, 0), L = Scan(); else { PUSH(RULE, 0); E = MakeExp(SymX, ID); goto END; } } else PUSH(RULE, 0); EXP: switch (L) { case LParT: PUSH(PAR, 0); L = Scan(); goto EXP; case LBrT: PUSH(OPT, 0); L = Scan(); goto EXP; case ZeroT: E = MakeExp(ZeroX); L = Scan(); goto END; case OneT: E = MakeExp(OneX); L = Scan(); goto END; case SymT: E = MakeExp(SymX, LastID); L = Scan(); goto END; default: ERROR("Corrupt expression."); return 0; } END: switch (Action[TOP][L]) { case 'A': ERROR("Extra ','"); L = Scan(); goto END; case 'B': ERROR("Unmatched )."); L = Scan(); goto END; case 'C': ERROR("Unmatched ]."); L = Scan(); goto END; case 'D': ERROR("Unmatched (."); POP(); goto END; case 'E': ERROR("Unmatched [."); POP(); goto MakeOpt; case 'F': ERROR("Left-hand side of '=' must be symbol."); exit(1); case 'G': ERROR("Missing ','."); ID->Value = E; POP(); goto LHS; case '$': POP(); return E; case ',': ID->Value = E; POP(); L = Scan(); goto LHS; case ')': POP(); L = Scan(); goto END; case ']': POP(); case '?': L = Scan(); MakeOpt: E = MakeExp(OptX, E); goto END; case 'x': E = CatExp(POP(), E); goto END; case 'v': E = BinExp(OrX, POP(), E); goto END; case 'X': E = BinExp(ProdX, POP(), E); goto END; case '~': E = MakeExp(DiffX, POP(), E); goto END; case '%': E = BinExp(AndX, POP(), E); goto END; case '.': PUSH(CAT, E); goto EXP; case '|': PUSH(OR, E); L = Scan(); goto EXP; case '-': PUSH(DIFF, E); L = Scan(); goto EXP; case '&': PUSH(AND, E); L = Scan(); goto EXP; case '^': PUSH(PROD, E); L = Scan(); goto EXP; case '*': L = Scan(); E = MakeExp(StarX, E); goto END; case '+': L = Scan(); E = MakeExp(PlusX, E); goto END; } return NULL; }
myTemp Munch::Exp(IR_myExp exp) { if (exp == nullptr) return nullptr; switch (exp->kind) { case IR_myExp_::IR_BinOperation: return BinExp(exp); case IR_myExp_::IR_Mem: return MemExp(exp); case IR_myExp_::IR_Temp: return TempExp(exp); case IR_myExp_::IR_ESeq: return ESeqExp(exp); case IR_myExp_::IR_Name: return NameExp(exp); case IR_myExp_::IR_Const: return ConstExp(exp); case IR_myExp_::IR_Call: return CallExp(exp); default: assert (false); } }
void FormStates(Exp E) { int S, I, Diff; Exp A, B; int AX, BX; STab = 0, Ss = 0; AddState(MakeExp(ZeroX)); AddState(E); TList = 0, TMax = 0; for (S = 0; S < Ss; S++) { PushQ(STab[S]); while (Xs > 0) { E = XStack[Xs - 1]; if (E->Normal) { PopQ(); continue; } switch (E->Tag) { case ZeroX: case OneX: E->Terms = 0, E->Sum = 0, E->Normal = 1; PopQ(); break; case SymX: E->Terms = 1, E->Sum = Allocate(sizeof *E->Sum); E->Sum[0].X = E->Body.Leaf, E->Sum[0].Q = MakeExp(OneX); E->Normal = 1; PopQ(); break; case OptX: A = E->Body.Arg[0]; if (!A->Normal) { PushQ(A); continue; } E->Terms = A->Terms, E->Sum = A->Sum; E->Normal = 1; PopQ(); break; case StarX: case PlusX: A = E->Body.Arg[0]; if (!A->Normal) { PushQ(A); continue; } B = E->Unit? E: MakeExp(StarX, A); Catenate: E->Terms = A->Terms; E->Sum = Allocate(E->Terms * sizeof *E->Sum); for (I = 0; I < E->Terms; I++) E->Sum[I].X = A->Sum[I].X, E->Sum[I].Q = CatExp(A->Sum[I].Q, B); E->Normal = 1; PopQ(); break; case CatX: case OrX: case AndX: case DiffX: case ProdX: A = E->Body.Arg[0]; if (!A->Normal) { PushQ(A); continue; } B = E->Body.Arg[1]; if (E->Tag == CatX && !A->Unit) goto Catenate; if (!B->Normal) { PushQ(B); continue; } for (AX = BX = Ts = 0; AX < A->Terms || BX < B->Terms; ) { Exp dA, dB; Symbol xA, xB; Diff = 0; if (AX >= A->Terms) Diff = 1; else dA = A->Sum[AX].Q, xA = A->Sum[AX].X; if (BX >= B->Terms) Diff = -1; else dB = B->Sum[BX].Q, xB = B->Sum[BX].X; if (Diff == 0) Diff = strcmp(xA->Name, xB->Name); if (Diff <= 0) AX++; if (Diff >= 0) BX++; switch (E->Tag) { case AndX: if (Diff == 0) AddTerm(xA, BinExp(AndX, dA, dB)); break; case CatX: if (Diff <= 0) dA = CatExp(dA, B); goto Join; case ProdX: if (Diff <= 0) dA = BinExp(ProdX, dA, B); if (Diff >= 0) dB = BinExp(ProdX, dB, A); case OrX: Join: if (Diff < 0) AddTerm(xA, dA); else if (Diff > 0) AddTerm(xB, dB); else AddTerm(xA, BinExp(OrX, dA, dB)); break; case DiffX: if (Diff == 0) dA = MakeExp(DiffX, dA, dB); if (Diff <= 0) AddTerm(xA, dA); break; default: break; } } E->Terms = Ts; E->Sum = Allocate(E->Terms * sizeof *E->Sum); for (I = 0; I < Ts; I++) E->Sum[I] = TList[I]; E->Normal = 1; PopQ(); break; } } E = STab[S]; for (I = 0; I < E->Terms; I++) AddState(E->Sum[I].Q); } free(XStack), XMax = 0; free(TList), TMax = 0; }