/** * Determines whether the given follow restriction matches the remaining input * string. It is used to determine if the associated reduction should be * performed. * * \param inputString the input string. * \param restrictions the follow restriction to compare against the input * string. * * \return \c true if the restriction does not match the input string; * \c false otherwise. */ ATbool IS_checkLookahead(InputString inputString, PTBL_Restrictions restrictions) { PTBL_Restriction restriction; PT_Symbols charClasses; PT_Symbol cc; ATbool permitted = ATtrue; int index; for (; permitted && !PTBL_isRestrictionsEmpty(restrictions); restrictions = PTBL_getRestrictionsTail(restrictions)) { restriction = PTBL_getRestrictionsHead(restrictions); index = inputString->index; charClasses = (PT_Symbols)PTBL_getRestrictionCharClasses(restriction); while (!PT_isSymbolsEmpty(charClasses)) { cc = PT_getSymbolsHead(charClasses); charClasses = PT_getSymbolsTail(charClasses); index++; /* If at end of input no lookahead restrictions apply. */ if (IS_getLength(inputString) == index) { break; } if (PT_elementOfCharClass(PT_makeTreeChar(getToken(inputString, index)), cc) && PT_isSymbolsEmpty(charClasses)) { permitted = ATfalse; } } } return permitted; }
static void first(CC_Class *cc, PT_Symbols symbols) { PT_Symbol symbol; CC_Class *set; while(!PT_isSymbolsEmpty(symbols)) { symbol = PT_getSymbolsHead(symbols); symbols = PT_getSymbolsTail(symbols); set = get_first_set(symbol, ATtrue); CC_union(cc, set, cc); if (!CC_containsChar(set, CC_EPSILON)) { CC_removeChar(cc, CC_EPSILON); return; } } CC_addChar(cc, CC_EPSILON); }
static PT_Symbols renameInSymbols(PT_Symbols symbols, PT_Symbol formalParam, PT_Symbol actualParam) { if (PT_isSymbolsEmpty(symbols)) { return symbols; } else { PT_Symbol head = PT_getSymbolsHead(symbols); PT_Symbols tail = PT_getSymbolsTail(symbols); PT_Symbol newHead = renameInSymbol(head, formalParam, actualParam); PT_Symbols newTail = renameInSymbols(tail, formalParam, actualParam); return PT_setSymbolsHead(PT_setSymbolsTail(symbols, newTail), newHead); } }
ATbool PT_isProductionVariable(PT_Production prod) { /* This implements: "prod([varsym(<term>)],cf(<term>),<term>)" */ if (PT_isProductionDefault(prod)) { PT_Symbols lhs = PT_getProductionLhs(prod); PT_Symbol rhs = PT_getProductionRhs(prod); if ((PT_isSymbolCf(rhs) || PT_isSymbolLex(rhs)) && PT_hasSymbolsHead(lhs)) { PT_Symbol lhssym = PT_getSymbolsHead(lhs); PT_Symbols tail = PT_getSymbolsTail(lhs); return PT_isSymbolsEmpty(tail) && PT_isSymbolVarSym(lhssym); } return ATfalse; } return ATfalse; }
/* For each symbol on the left hand side of the given production rule, if the * symbol is a non-terminal initialise the symbol's first set to empty, * otherwise if the symbol is a terminal or the end-of-string symbol, * initialise the symbol's first set to the symbol. */ void init_prod_first(PT_Production prod) { PT_Symbols symbols; PT_Symbol symbol; CC_Class *set; CC_Class *newset; symbols = PT_getProductionLhs(prod); while(!PT_isSymbolsEmpty(symbols)) { symbol = PT_getSymbolsHead(symbols); set = get_first_set(symbol, ATtrue); newset = CC_getCharClass(symbol); /*assert(CC_isEmpty(set) || CC_isEqual(set, newset));*/ CC_copy(newset, set); symbols = PT_getSymbolsTail(symbols); } }
ATbool PT_isLexicalInjectionProd(PT_Production prod) { /* This implements: "prod([lex(<term>)],cf(<term>),<term>)" */ if (PT_isProductionDefault(prod)) { PT_Symbols lhs = PT_getProductionLhs(prod); PT_Symbol rhs = PT_getProductionRhs(prod); if (PT_isSymbolCf(rhs) && PT_hasSymbolsHead(lhs)) { PT_Symbol rhsNestedSymbol = PT_getSymbolSymbol(rhs); PT_Symbol lhssym = PT_getSymbolsHead(lhs); PT_Symbols tail = PT_getSymbolsTail(lhs); if (PT_isSymbolsEmpty(tail) && PT_isSymbolLex(lhssym)) { PT_Symbol lhsNestedSymbol = PT_getSymbolSymbol(lhssym); return PT_isEqualSymbol(rhsNestedSymbol, lhsNestedSymbol); } } return ATfalse; } return ATfalse; }
static PT_Production normalizeProduction(PT_Production prod) { PT_Symbol layout = PT_makeOptLayoutSymbol(); if (!PT_isProductionList(prod)) { PT_Symbols lhs = PT_getProductionLhs(prod); PT_Symbols newLhs = PT_makeSymbolsEmpty(); PT_Symbol rhs = PT_getProductionRhs(prod); for(; !PT_isSymbolsEmpty(lhs); lhs = PT_getSymbolsTail(lhs)) { PT_Symbol head = PT_getSymbolsHead(lhs); PT_Symbol newHead; if (!PT_isSymbolLit(head)) { newHead = PT_makeSymbolCf(head); } else { newHead = head; } newLhs = PT_makeSymbolsList(newHead, newLhs); if (PT_hasSymbolsTail(PT_getSymbolsTail(lhs))) { newLhs = PT_makeSymbolsList(layout, newLhs); } } prod = PT_setProductionRhs(prod, PT_makeSymbolCf(rhs)); prod = PT_setProductionLhs(prod, PT_reverseSymbols(newLhs)); return prod; } else { return prod; } }
SDF_Symbol PTSymbolToSDFSymbol(PT_Symbol ptSymbol) { SDF_Symbol result; if (PT_isSymbolLit(ptSymbol)) { char *str = PT_getSymbolString(ptSymbol); char *qstr = escape(str, "\"\\", QUOTED); SDF_Literal lit = SDF_makeLiteralQlit(SDF_makeQLiteralQuoted(SDF_makeCHARLISTString(qstr))); free(qstr); result = SDF_makeSymbolLit(lit); } else if (PT_isSymbolCf(ptSymbol) || PT_isSymbolLex(ptSymbol) || PT_isSymbolVarSym(ptSymbol)) { result = PTSymbolToSDFSymbol(PT_getSymbolSymbol(ptSymbol)); } else if (PT_isSymbolEmpty(ptSymbol)) { result = SDF_makeSymbolEmpty(SDF_makeLayoutEmpty()); } else if (PT_isSymbolSeq(ptSymbol)) { PT_Symbols ptSymbols = PT_getSymbolSymbols(ptSymbol); PT_Symbol ptHead = PT_getSymbolsHead(ptSymbols); SDF_Symbol sdfHead = PTSymbolToSDFSymbol(ptHead); PT_Symbols ptTail = PT_getSymbolsTail(ptSymbols); if (PT_isSymbolsEmpty(ptTail)) { ATabort("PTSymbolToSDFSymbol: empty tail in %s\n", PT_yieldSymbol(ptSymbol)); result = NULL; } else { SDF_SymbolTail sdfSymbolTail = (SDF_SymbolTail)PTSymbolsToSDFSymbolList(ptTail); result = SDF_makeSymbolSeq(SDF_makeLayoutEmpty(), sdfHead, SDF_makeLayoutSpace(), sdfSymbolTail, SDF_makeLayoutEmpty()); } } else if (PT_isSymbolOpt(ptSymbol)) { SDF_Symbol sdfSymbol = PTSymbolToSDFSymbol(PT_getSymbolSymbol(ptSymbol)); result = SDF_makeSymbolOpt(sdfSymbol, SDF_makeLayoutEmpty()); } else if (PT_isSymbolAlt(ptSymbol)) { SDF_Symbol sdfLhs = PTSymbolToSDFSymbol(PT_getSymbolLhs(ptSymbol)); SDF_Symbol sdfRhs = PTSymbolToSDFSymbol(PT_getSymbolRhs(ptSymbol)); result = SDF_makeSymbolAlt(sdfLhs, SDF_makeLayoutEmpty(), SDF_makeLayoutEmpty(), sdfRhs); } else if (PT_isSymbolTuple(ptSymbol)) { SDF_Symbol sdfHead = PTSymbolToSDFSymbol(PT_getSymbolHead(ptSymbol)); SDF_SymbolRest sdfRest = PTSymbolsToSDFSymbolRest(PT_getSymbolRest(ptSymbol)); result = SDF_makeSymbolTuple(SDF_makeLayoutEmpty(), sdfHead, SDF_makeLayoutEmpty(), SDF_makeLayoutEmpty(), sdfRest, SDF_makeLayoutEmpty()); } else if (PT_isSymbolSort(ptSymbol)) { char *str = PT_getSymbolSort(ptSymbol); SDF_Sort sort = SDF_makeSortMoreChars(SDF_makeCHARLISTString(str)); result = SDF_makeSymbolSort(sort); } else if (PT_isSymbolIterPlus(ptSymbol)) { SDF_Symbol sdfSymbol = PTSymbolToSDFSymbol(PT_getSymbolSymbol(ptSymbol)); result = SDF_makeSymbolIter(sdfSymbol, SDF_makeLayoutEmpty()); } else if (PT_isSymbolIterStar(ptSymbol)) { SDF_Symbol sdfSymbol = PTSymbolToSDFSymbol(PT_getSymbolSymbol(ptSymbol)); result = SDF_makeSymbolIterStar(sdfSymbol, SDF_makeLayoutEmpty()); } else if (PT_isSymbolIterPlusSep(ptSymbol)) { SDF_Symbol sdfSymbol = PTSymbolToSDFSymbol(PT_getSymbolSymbol(ptSymbol)); SDF_Symbol sdfSep = PTSymbolToSDFSymbol(PT_getSymbolSeparator(ptSymbol)); result = SDF_makeSymbolIterSep(SDF_makeLayoutEmpty(), sdfSymbol, SDF_makeLayoutSpace(), sdfSep, SDF_makeLayoutEmpty(), SDF_makeLayoutEmpty()); } else if (PT_isSymbolIterStarSep(ptSymbol)) { SDF_Symbol sdfSymbol = PTSymbolToSDFSymbol(PT_getSymbolSymbol(ptSymbol)); SDF_Symbol sdfSep = PTSymbolToSDFSymbol(PT_getSymbolSeparator(ptSymbol)); result = SDF_makeSymbolIterStarSep(SDF_makeLayoutEmpty(), sdfSymbol, SDF_makeLayoutSpace(), sdfSep, SDF_makeLayoutEmpty(), SDF_makeLayoutEmpty()); } else if (PT_isSymbolIterN(ptSymbol)) { char str[BUFSIZ]; SDF_Symbol sdfSymbol = PTSymbolToSDFSymbol(PT_getSymbolSymbol(ptSymbol)); int nr = PT_getSymbolNumber(ptSymbol); SDF_NatCon sdfNatCon; sprintf(str, "%d", nr); sdfNatCon = SDF_makeNatConDigits(SDF_makeCHARLISTString(str)); result = SDF_makeSymbolIterN(sdfSymbol, SDF_makeLayoutSpace(), sdfNatCon, SDF_makeLayoutEmpty()); } else if (PT_isSymbolIterSepN(ptSymbol)) { char str[BUFSIZ]; SDF_Symbol sdfSymbol = PTSymbolToSDFSymbol(PT_getSymbolSymbol(ptSymbol)); SDF_Symbol sdfSep = PTSymbolToSDFSymbol(PT_getSymbolSeparator(ptSymbol)); int nr = PT_getSymbolNumber(ptSymbol); SDF_NatCon sdfNatCon; sprintf(str, "%d", nr); sdfNatCon = SDF_makeNatConDigits(SDF_makeCHARLISTString(str)); result = SDF_makeSymbolIterSepN(SDF_makeLayoutEmpty(), sdfSymbol, SDF_makeLayoutSpace(), sdfSep, SDF_makeLayoutEmpty(), SDF_makeLayoutEmpty(), sdfNatCon, SDF_makeLayoutEmpty()); } else if (PT_isSymbolLayout(ptSymbol)) { ATabort("PTSymbolToSDFSymbol: layout.\n"); result = NULL; } else { ATabort("PTSymbolToSDFSymbol: unable to convert symbol %t: %s\n", ptSymbol, PT_yieldSymbol(ptSymbol)); result = NULL; } return result; }