Пример #1
0
Exp BinExp(ExpTag Tag, Exp A, Exp B) {
   Exp C, D; int Diff;
   for (As = 0; A->Tag == Tag; A = A->Body.Arg[1]) InsertA(A->Body.Arg[0]);
   for (Bs = 0; B->Tag == Tag; B = B->Body.Arg[1]) InsertB(B->Body.Arg[0]);
   if (A->ID > B->ID) C = A, InsertB(B); else C = B, InsertA(A);
   As--, Bs--;
   while (As >= 0 || Bs >= 0) {
      Diff = 0;
      if (As >= 0) A = AStack[As]; else Diff = -1;
      if (Bs >= 0) B = BStack[Bs]; else Diff = +1;
      if (Diff == 0) Diff = A->ID - B->ID;
      if (Diff <= 0) Bs--, D = B; else As--, D = A;
      if (Diff == 0 && Tag != ProdX) As--;
      if (Tag == OrX) {
         if (C->Tag == ZeroX) { C = D; continue; }
         if (D->Tag == ZeroX || D == C) continue;
      } else {
         if (D->Tag == ZeroX || C->Tag == OneX) { C = D; continue; }
         if (D->Tag == OneX || C->Tag == ZeroX) continue;
         if (Tag != ProdX && D == C) continue;
      }
      C = MakeExp(Tag, D, C);
   }
   return C;
}
Пример #2
0
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;
}
Пример #3
0
Exp CatExp(Exp A, Exp B) {
   Exp E;
   for (As = 0; A->Tag == CatX; A = A->Body.Arg[1]) InsertA(A->Body.Arg[0]);
   InsertA(A);
   while (As-- > 0) {
      E = AStack[As];
      if (E->Tag == ZeroX || B->Tag == OneX) B = E;
      else if (E->Tag == OneX || B->Tag == ZeroX) ;
      else B = MakeExp(CatX, E, B);
   }
   return B;
}
Пример #4
0
void
FormState(int Q)
{

  int I, S, S1, X; 
  int qX, Q1, Q2;
  int A, B;
  State SP;
  Exp E, E1;

  IBuf = NULL;
  IMax = 0;
  STab = NULL;
  Ss = 0; 
  AddState(1, &Q);

  for (S = 0; S < Ss; S++) 
    {
      SP = &STab[S];
      for (Xs = 0, S1 = 0; S1 < SP->States; S1++) 
        PushQ(SP->SList[S1]);
      for (SP->Empty = 0, Is = 0, X = 0; X < Xs; X++)  {
        qX = XStack[X];
      EVALUATE:
        E = EquTab[qX].Value;
        switch (E->Tag)  {
        case SymX:
          AddBuf(E->Body.Leaf, MakeExp(-1, OneX));
          break;
        case OneX:
          SP->Empty = 1;
          break;
        case ZeroX:
          break;
        case OptX:
          Q1 = E->Body.Arg[0];
          MakeExp(qX, OrX, MakeExp(-1, OneX), E->Body.Arg[0]);
          goto EVALUATE;
        case PlusX:
          Q1 = E->Body.Arg[0];
          MakeExp(qX, AndX, Q1, MakeExp(-1, StarX, Q1));
          goto EVALUATE;
        case StarX:
          Q1 = E->Body.Arg[0];
          MakeExp(qX, OrX, MakeExp(-1, OneX), MakeExp(-1, PlusX, Q1));
          goto EVALUATE;
        case OrX:
          Q1 = E->Body.Arg[0];
          Q2 = E->Body.Arg[1];
          PushQ(Q1);
          PushQ(Q2);
          break;
        case AndX:
          Q1 = E->Body.Arg[0], Q2 = E->Body.Arg[1];
          E1 = EquTab[Q1].Value;
          switch (E1->Tag) {
          case SymX:
            AddBuf(E1->Body.Leaf, Q2);
            break;
          case OneX:
            EquTab[qX].Value = EquTab[Q2].Value;
            goto EVALUATE;
          case ZeroX:
            MakeExp(qX, ZeroX);
            break;
          case OptX:
            A = E1->Body.Arg[0];
            MakeExp(qX, OrX, Q2, MakeExp(-1, AndX, A, Q2));
            goto EVALUATE;
          case PlusX:
            A = E1->Body.Arg[0];
            MakeExp(qX, AndX, A, MakeExp(-1, OrX, Q2, qX));
            goto EVALUATE;
          case StarX:
            A = E1->Body.Arg[0];
            MakeExp(qX, OrX, Q2, MakeExp(-1, AndX, A, qX));
            goto EVALUATE;
          case OrX:
            A = E1->Body.Arg[0], B = E1->Body.Arg[1];
            MakeExp(qX, OrX,
                    MakeExp(-1, AndX, A, Q2), MakeExp(-1, AndX, B, Q2));
            goto EVALUATE;
          case AndX:
            A = E1->Body.Arg[0], B = E1->Body.Arg[1];
            MakeExp(qX, AndX, A, MakeExp(-1, AndX, B, Q2));
            goto EVALUATE;
          }
        }
      }
      while (Xs > 0) 
        PopQ();
      SP->Shifts = Is;
      SP->ShList = cl_malloc(sizeof *SP->ShList * Is);
      for (I = 0; I < Is; I++)  {
        int rhs_state = -1;
        SP->ShList[I].LHS = IBuf[I].LHS;
        rhs_state = AddState(IBuf[I].Size, IBuf[I].RHS);
        SP = &STab[S];        /* AddState() might have reallocated state table -> update pointer */
        SP->ShList[I].RHS = rhs_state;
      }
    }
  free(IBuf);
  IBuf = 0;
  Is = IMax = 0;
}
Пример #5
0
/** the regex parser proper: private function */
int
Parse(void)
{
  Lexical L; 
  Symbol ID = NULL; 
  int RHS; 
  
  int ignore_value;             /* ignore value of POP() macro */

  SP = Stack;
 LHS:
  /* get next symbol from the lexer */
  L = LEX();
  if (L == IdenT) 
    {
      ID = LookUp(LastW); 
      L = LEX();
      if (L == EqualT) 
        {
          PUSH(EQU, -1);
          L = LEX();
        } 
      else 
        {
          PUSH(RULE, -1);
          RHS = MakeExp(-1, SymX, ID); 
          goto END;
        }
    } 
  else 
    PUSH(RULE, -1);
 EXP:
  switch (L)   {
  case LParT:
    PUSH(PAR, -1);
    L = LEX();
    goto EXP;
  case LBrT:
    PUSH(OPT, -1);
    L = LEX();
    goto EXP;
  case ZeroT:
    RHS = MakeExp(-1, ZeroX);
    L = LEX();
    goto END;
  case OneT:
    RHS = MakeExp(-1, OneX);
    L = LEX();
    goto END;
  case IdenT:
    RHS = MakeExp(-1, SymX, LookUp(LastW));
    L = LEX();
    goto END;
  default:
    REGEX2DFA_ERROR("Corrupt expression.");
    return -1;
  }
  
 END:
  switch (Action[TOP][L])  {
  case 'A':
    REGEX2DFA_ERROR("Extra ','");
    rcqp_receive_error(1);
  case 'B':
    REGEX2DFA_ERROR("Unmatched ).");
    L = LEX();
    goto END;
  case 'C':
    REGEX2DFA_ERROR("Unmatched ].");
    L = LEX();
    goto END;
  case 'D':
    REGEX2DFA_ERROR("Unmatched (.");
    ignore_value = POP();
    goto END;
  case 'E':
    REGEX2DFA_ERROR("Unmatched [.");
    goto MakeOpt;
  case 'F':
    REGEX2DFA_ERROR("( ... ].");
    ignore_value = POP();
    L = LEX();
    goto END;
  case 'G':
    REGEX2DFA_ERROR("[ ... ).");
    L = LEX();
    goto MakeOpt;
  case 'H':
    REGEX2DFA_ERROR("Left-hand side of '=' must be symbol.");
    rcqp_receive_error(1);
  case 'I':
    REGEX2DFA_ERROR("Missing evaluation.");
    rcqp_receive_error(1);
  case '.':
    ignore_value = POP();
    return RHS;
  case ')':
    ignore_value = POP();
    L = LEX();
    goto END;
  case ']':
    L = LEX();
  MakeOpt:
    ignore_value = POP();
    RHS = MakeExp(-1, OptX, RHS);
    goto END;
  case '=':
    Store(ID, RHS);
    ignore_value = POP();
    goto LHS;
  case 'v':
    RHS = MakeExp(-1, OrX, POP(), RHS);
    goto END;
  case 'x':
    RHS = MakeExp(-1, AndX, POP(), RHS);
    goto END;
  case '*':
    RHS = MakeExp(-1, StarX, RHS);
    L = LEX();
    goto END;
  case '+':
    RHS = MakeExp(-1, PlusX, RHS);
    L = LEX();
    goto END;
  case '|':
    PUSH(OR, RHS); L = LEX();
    goto EXP;
  case '&':
    PUSH(AND, RHS);
    goto EXP;
  }

  assert(0 && "Not reached");
  return 0;
}
Пример #6
0
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;
}