diff options
author | Adrian Thurston <thurston@complang.org> | 2009-02-25 02:43:27 +0000 |
---|---|---|
committer | Adrian Thurston <thurston@complang.org> | 2009-02-25 02:43:27 +0000 |
commit | ff17942e8101c03b1dfa7a2f8dd61b4393630e39 (patch) | |
tree | 3b35739dfb857bd88f811eb7a817c997a20ba5bb | |
parent | 9fcbafb9dfa6fc741177b5ba126a0aa4ed9f2f38 (diff) | |
download | colm-ff17942e8101c03b1dfa7a2f8dd61b4393630e39.tar.gz |
Added the plus operator.
-rw-r--r-- | colm/compile.cpp | 6 | ||||
-rw-r--r-- | colm/lmparse.kl | 28 | ||||
-rw-r--r-- | colm/parsedata.cpp | 58 | ||||
-rw-r--r-- | colm/parsedata.h | 17 | ||||
-rw-r--r-- | colm/parsetree.h | 18 | ||||
-rw-r--r-- | colm/pdabuild.cpp | 2 | ||||
-rw-r--r-- | colm/pdacodegen.cpp | 1 | ||||
-rw-r--r-- | colm/pdarun.h | 1 | ||||
-rw-r--r-- | colm/tree.cpp | 5 |
9 files changed, 101 insertions, 35 deletions
diff --git a/colm/compile.cpp b/colm/compile.cpp index 1f6068bb..918b9712 100644 --- a/colm/compile.cpp +++ b/colm/compile.cpp @@ -218,10 +218,12 @@ UniqueType *TypeRef::lookupType( ParseData *pd ) uniqueType = pd->findUniqueType( TYPE_TREE, factor->langEl ); else { String name = typeName; - if ( isOpt ) + if ( repeatType == RepeatOpt ) name.setAs( 32, "_opt_%s", name.data ); - else if ( isRepeat ) + else if ( repeatType == RepeatRepeat ) name.setAs( 32, "_repeat_%s", name.data ); + else if ( repeatType == RepeatList ) + name.setAs( 32, "_list_%s", name.data ); /* Not an iterator. May be a reference. */ uniqueType = lookupTypePart( pd, nspaceQual, name ); diff --git a/colm/lmparse.kl b/colm/lmparse.kl index 510a9127..beb70bc8 100644 --- a/colm/lmparse.kl +++ b/colm/lmparse.kl @@ -276,7 +276,7 @@ pred_token: region_qual TK_Word final { $$->factor = new PdaFactor( $2->loc, false, $1->nspaceQual, - $2->data, 0, false, false ); + $2->data, 0, RepeatNone, false, false ); pd->resolveReferenceFactor( $$->factor ); }; @@ -285,7 +285,7 @@ pred_token: final { PdaLiteral *literal = new PdaLiteral( $2->loc, *$2 ); $$->factor = new PdaFactor( $2->loc, false, $1->nspaceQual, - literal, 0, false, false ); + literal, 0, RepeatNone, false, false ); pd->resolveLiteralFactor( $$->factor ); }; @@ -383,15 +383,13 @@ nonterm basic_type_ref uses type_ref; basic_type_ref: region_qual TK_Word opt_repeat final { $$->typeRef = new TypeRef( $2->loc, $1->nspaceQual, $2->data ); - $$->typeRef->isRepeat = $3->repeat; - $$->typeRef->isOpt = $3->opt; + $$->typeRef->repeatType = $3->repeatType; }; basic_type_ref: KW_Ptr region_qual TK_Word opt_repeat final { $$->typeRef = new TypeRef( $1->loc, $2->nspaceQual, $3->data ); - $$->typeRef->isRepeat = $4->repeat; - $$->typeRef->isOpt = $4->opt; + $$->typeRef->repeatType = $4->repeatType; $$->typeRef->isPtr = true; }; @@ -507,7 +505,7 @@ nonterm pattern_el_type_or_lit pattern_el_type_or_lit: region_qual TK_Word opt_repeat final { PdaFactor *factor = new PdaFactor( $2->loc, false, $1->nspaceQual, - $2->data, 0, $3->opt, $3->repeat ); + $2->data, 0, $3->repeatType, $3->opt, $3->repeat ); $$->patternItem = new PatternItem( $2->loc, factor, PatternItem::FactorType ); patternItemList->append( $$->patternItem ); }; @@ -516,7 +514,7 @@ pattern_el_type_or_lit: region_qual TK_Literal opt_repeat final { PdaLiteral *literal = new PdaLiteral( $2->loc, *$2 ); PdaFactor *factor = new PdaFactor( $2->loc, false, $1->nspaceQual, - literal, 0, $3->opt, $3->repeat ); + literal, 0, $3->repeatType, $3->opt, $3->repeat ); $$->patternItem = new PatternItem( $2->loc, factor, PatternItem::FactorType ); patternItemList->append( $$->patternItem ); }; @@ -571,7 +569,7 @@ repl_el: region_qual TK_Literal final { PdaLiteral *literal = new PdaLiteral( $2->loc, *$2 ); PdaFactor *factor = new PdaFactor( $2->loc, false, $1->nspaceQual, - literal, 0, false, false ); + literal, 0, RepeatNone, false, false ); ReplItem *replItem = new ReplItem( $2->loc, ReplItem::FactorType, factor ); replItemList->append( replItem ); }; @@ -596,7 +594,7 @@ prod_el: opt_commit region_qual TK_Word opt_repeat final { $$->factor = new PdaFactor( $3->loc, $1->commit, - $2->nspaceQual, $3->data, 0, $4->opt, $4->repeat ); + $2->nspaceQual, $3->data, 0, $4->repeatType, $4->opt, $4->repeat ); }; prod_el: @@ -605,18 +603,20 @@ prod_el: /* Create a new factor node going to a concat literal. */ PdaLiteral *literal = new PdaLiteral( $3->loc, *$3 ); $$->factor = new PdaFactor( $3->loc, $1->commit, $2->nspaceQual, - literal, 0, $4->opt, $4->repeat ); + literal, 0, $4->repeatType, $4->opt, $4->repeat ); }; nonterm opt_repeat { bool opt; bool repeat; + RepeatType repeatType; }; -opt_repeat: '?' final { $$->opt = true; $$->repeat = false; }; -opt_repeat: '*' final { $$->opt = false; $$->repeat = true; }; -opt_repeat: final { $$->opt = false; $$->repeat = false; }; +opt_repeat: '*' final { $$->opt = false; $$->repeat = true; $$->repeatType = RepeatRepeat; }; +opt_repeat: '+' final { $$->opt = false; $$->repeat = false; $$->repeatType = RepeatList; }; +opt_repeat: '?' final { $$->opt = true; $$->repeat = false; $$->repeatType = RepeatOpt; }; +opt_repeat: final { $$->opt = false; $$->repeat = false; $$->repeatType = RepeatNone; }; nonterm region_qual { diff --git a/colm/parsedata.cpp b/colm/parsedata.cpp index 5bcb1282..4d91fbaa 100644 --- a/colm/parsedata.cpp +++ b/colm/parsedata.cpp @@ -1140,7 +1140,7 @@ void ParseData::resolveReferenceFactor( PdaFactor *fact ) /* Look up the language element in the region. */ KlangEl *langEl = getKlangEl( this, nspace, fact->refName ); - if ( fact->opt ) { + if ( fact->repeatType == RepeatOpt ) { /* If the factor is an opt, create the opt element and link the factor * to it. */ String optName( 32, "_opt_%s", fact->refName.data ); @@ -1158,7 +1158,7 @@ void ParseData::resolveReferenceFactor( PdaFactor *fact ) /* Build the first production of the repeat. */ PdaFactor *factor1 = new PdaFactor( InputLoc(), false, fact->nspaceQual, - fact->refName, 0, false, false ); + fact->refName, 0, RepeatNone, false, false ); prodElList1->append( factor1 ); Definition *newDef1 = new Definition( InputLoc(), @@ -1181,7 +1181,7 @@ void ParseData::resolveReferenceFactor( PdaFactor *fact ) fact->langEl = prodName; } } - else if ( fact->repeat ) { + else if ( fact->repeatType == RepeatRepeat ) { /* If the factor is a repeat, create the repeat element and link the * factor to it. */ String repeatName( 32, "_repeat_%s", fact->refName.data ); @@ -1199,9 +1199,9 @@ void ParseData::resolveReferenceFactor( PdaFactor *fact ) /* Build the first production of the repeat. */ PdaFactor *factor1 = new PdaFactor( InputLoc(), false, fact->nspaceQual, - fact->refName, 0, false, false ); + fact->refName, 0, RepeatNone, false, false ); PdaFactor *factor2 = new PdaFactor( InputLoc(), false, fact->nspaceQual, - repeatName, 0, false, false ); + repeatName, 0, RepeatNone, false, false ); prodElList1->append( factor1 ); prodElList1->append( factor2 ); @@ -1226,6 +1226,54 @@ void ParseData::resolveReferenceFactor( PdaFactor *fact ) fact->langEl = prodName; } } + else if ( fact->repeatType == RepeatList ) { + /* If the factor is a repeat, create the repeat element and link the + * factor to it. */ + String repeatName( 32, "_list_%s", fact->refName.data ); + + SymbolMapEl *inDict = nspace->symbolMap.find( repeatName ); + if ( inDict != 0 ) { + fact->langEl = inDict->value; + } + else { + KlangEl *prodName = getKlangEl( this, nspace, repeatName ); + prodName->type = KlangEl::NonTerm; + prodName->isList = true; + + /* Build the first production of the list. */ + PdaFactor *factor1 = new PdaFactor( InputLoc(), false, fact->nspaceQual, + fact->refName, 0, RepeatNone, false, false ); + PdaFactor *factor2 = new PdaFactor( InputLoc(), false, fact->nspaceQual, + repeatName, 0, RepeatNone, false, false ); + + ProdElList *prodElList1 = new ProdElList; + prodElList1->append( factor1 ); + prodElList1->append( factor2 ); + + Definition *newDef1 = new Definition( InputLoc(), + prodName, prodElList1, false, 0, + prodList.length(), Definition::Production ); + + prodName->defList.append( newDef1 ); + prodList.append( newDef1 ); + + /* Build the second production of the list. */ + PdaFactor *factor3 = new PdaFactor( InputLoc(), false, fact->nspaceQual, + fact->refName, 0, RepeatNone, false, false ); + + ProdElList *prodElList2 = new ProdElList; + prodElList2->append( factor3 ); + + Definition *newDef2 = new Definition( InputLoc(), + prodName, prodElList2, false, 0, + prodList.length(), Definition::Production ); + + prodName->defList.append( newDef2 ); + prodList.append( newDef2 ); + + fact->langEl = prodName; + } + } else { /* The factor is not a repeat. Link to the language element. */ fact->langEl = langEl; diff --git a/colm/parsedata.h b/colm/parsedata.h index 1e69935b..28db05ab 100644 --- a/colm/parsedata.h +++ b/colm/parsedata.h @@ -181,6 +181,7 @@ struct KlangEl : public DListEl<KlangEl> bool reduceFirst; bool isLiteral; bool isRepeat; + bool isList; bool isOpt; bool parseStop; bool isEOF; @@ -225,25 +226,26 @@ struct PdaFactor /* Construct with a literal fsm. */ PdaFactor( const InputLoc &loc, bool commit, NamespaceQual *nspaceQual, - PdaLiteral *literal, int priorVal, bool opt, bool repeat ) : + PdaLiteral *literal, int priorVal, RepeatType repeatType, bool opt, bool repeat ) : loc(loc), commit(commit), nspaceQual(nspaceQual), - literal(literal), langEl(0), priorVal(priorVal), opt(opt), repeat(repeat), + literal(literal), langEl(0), priorVal(priorVal), repeatType(repeatType), nspace(0), type(LiteralType), objField(0) {} /* Construct with a reference to a var def. */ PdaFactor( const InputLoc &loc, bool commit, NamespaceQual *nspaceQual, - const String &refName, int priorVal, bool opt, bool repeat ) : + const String &refName, int priorVal, RepeatType repeatType, bool opt, bool repeat ) : loc(loc), commit(commit), nspaceQual(nspaceQual), refName(refName), - literal(0), langEl(0), priorVal(priorVal), opt(opt), repeat(repeat), + literal(0), langEl(0), priorVal(priorVal), repeatType(repeatType), nspace(0), type(ReferenceType), objField(0) {} PdaFactor( const InputLoc &loc, KlangEl *langEl ) : loc(loc), commit(false), nspaceQual(0), literal(0), langEl(langEl), - priorVal(0), opt(false), repeat(false), nspace(0), type(ReferenceType), objField(0) {} + priorVal(0), repeatType(RepeatNone), nspace(0), + type(ReferenceType), objField(0) {} PdaFactor() : commit(false), nspaceQual(0), - literal(0), langEl(0), priorVal(0), opt(false), repeat(false), + literal(0), langEl(0), priorVal(0), repeatType(RepeatNone), nspace(0), type(LiteralType), objField(0) {} InputLoc loc; @@ -253,8 +255,7 @@ struct PdaFactor PdaLiteral *literal; KlangEl *langEl; int priorVal; - bool opt; - bool repeat; + RepeatType repeatType; Namespace *nspace; Type type; ObjField *objField; diff --git a/colm/parsetree.h b/colm/parsetree.h index a9e4f6c1..e4ef5e38 100644 --- a/colm/parsetree.h +++ b/colm/parsetree.h @@ -1091,25 +1091,32 @@ typedef AvlMapEl< StringVect, int > VectorTypeIdMapEl; typedef Vector<TypeRef*> TypeRefVect; +enum RepeatType { + RepeatRepeat, + RepeatList, + RepeatOpt, + RepeatNone +}; + struct TypeRef { /* Qualification and a type name. These require lookup. */ TypeRef( const InputLoc &loc, NamespaceQual *nspaceQual, String typeName ) : loc(loc), nspaceQual(nspaceQual), typeName(typeName), iterDef(0), searchTypeRef(0), factor(0), - isPtr(false), isRef(false), isRepeat(false), isOpt(false), + isPtr(false), isRef(false), repeatType(RepeatNone), uniqueType(0) {} /* Iterator definition. */ TypeRef( const InputLoc &loc, IterDef *iterDef, TypeRef *searchTypeRef ) : loc(loc), iterDef(iterDef), searchTypeRef(searchTypeRef), factor(0), - isPtr(false), isRef(false), isRepeat(false), isOpt(false), + isPtr(false), isRef(false), repeatType(RepeatNone), uniqueType(0) {} /* Unique type is given directly. */ TypeRef( const InputLoc &loc, UniqueType *uniqueType ) : loc(loc), nspaceQual(0), iterDef(0), searchTypeRef(0), factor(0), - isPtr(false), isRef(false), isRepeat(false), isOpt(false), + isPtr(false), isRef(false), repeatType(RepeatNone), uniqueType(uniqueType) {} /* A factor in a pattern. In the case of matches we need a type ref at @@ -1117,7 +1124,7 @@ struct TypeRef * to do it on demand. */ TypeRef( const InputLoc &loc, PdaFactor *factor ) : loc(loc), nspaceQual(0), iterDef(0), searchTypeRef(0), factor(factor), - isPtr(false), isRef(false), isRepeat(false), isOpt(false), + isPtr(false), isRef(false), repeatType(RepeatNone), uniqueType(0) {} @@ -1131,8 +1138,7 @@ struct TypeRef PdaFactor *factor; bool isPtr; bool isRef; - bool isRepeat; - bool isOpt; + RepeatType repeatType; private: UniqueType *lookupTypePart( ParseData *pd, NamespaceQual *nspaceQual, diff --git a/colm/pdabuild.cpp b/colm/pdabuild.cpp index 308a57ab..a616de1b 100644 --- a/colm/pdabuild.cpp +++ b/colm/pdabuild.cpp @@ -71,6 +71,7 @@ KlangEl::KlangEl( Namespace *nspace, const String &name, Type type ) reduceFirst(false), isLiteral(false), isRepeat(false), + isList(false), isOpt(false), parseStop(false), isEOF(false), @@ -1386,6 +1387,7 @@ void ParseData::makeRuntimeData() if ( lel != 0 ) { runtimeData->lelInfo[i].name = lel->fullLit; runtimeData->lelInfo[i].repeat = lel->isRepeat; + runtimeData->lelInfo[i].list = lel->isList; runtimeData->lelInfo[i].literal = lel->isLiteral; runtimeData->lelInfo[i].ignore = lel->ignore; runtimeData->lelInfo[i].frameId = -1; diff --git a/colm/pdacodegen.cpp b/colm/pdacodegen.cpp index 53530e80..f5d6de5e 100644 --- a/colm/pdacodegen.cpp +++ b/colm/pdacodegen.cpp @@ -177,6 +177,7 @@ void PdaCodeGen::writeRuntimeData( RuntimeData *runtimeData, PdaTables *pdaTable /* Repeat, literal, ignore flags. */ out << ", " << runtimeData->lelInfo[i].repeat << ", " << + runtimeData->lelInfo[i].list << ", " << runtimeData->lelInfo[i].literal << ", " << runtimeData->lelInfo[i].ignore << ", "; diff --git a/colm/pdarun.h b/colm/pdarun.h index 61039a7e..b95d8806 100644 --- a/colm/pdarun.h +++ b/colm/pdarun.h @@ -341,6 +341,7 @@ struct LangElInfo { const char *name; bool repeat; + bool list; bool literal; bool ignore; diff --git a/colm/tree.cpp b/colm/tree.cpp index d41b4fbf..dce1e5e8 100644 --- a/colm/tree.cpp +++ b/colm/tree.cpp @@ -560,6 +560,11 @@ rec_call: * right to the first child (repeated item). */ if ( lelInfo[((Kid*)vm_top())->tree->id].repeat ) kid = kid->tree->child; + + /* If we have a kid and the parent is a list (recursive prod of + * list) then go right to the first child. */ + if ( kid != 0 && lelInfo[((Kid*)vm_top())->tree->id].list ) + kid = kid->tree->child; } kid = (Kid*) vm_pop(); |