summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2009-02-25 02:43:27 +0000
committerAdrian Thurston <thurston@complang.org>2009-02-25 02:43:27 +0000
commitff17942e8101c03b1dfa7a2f8dd61b4393630e39 (patch)
tree3b35739dfb857bd88f811eb7a817c997a20ba5bb
parent9fcbafb9dfa6fc741177b5ba126a0aa4ed9f2f38 (diff)
downloadcolm-ff17942e8101c03b1dfa7a2f8dd61b4393630e39.tar.gz
Added the plus operator.
-rw-r--r--colm/compile.cpp6
-rw-r--r--colm/lmparse.kl28
-rw-r--r--colm/parsedata.cpp58
-rw-r--r--colm/parsedata.h17
-rw-r--r--colm/parsetree.h18
-rw-r--r--colm/pdabuild.cpp2
-rw-r--r--colm/pdacodegen.cpp1
-rw-r--r--colm/pdarun.h1
-rw-r--r--colm/tree.cpp5
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();