diff options
author | Adrian Thurston <thurston@colm.net> | 2018-12-17 14:10:50 +0200 |
---|---|---|
committer | Adrian Thurston <thurston@colm.net> | 2018-12-17 14:11:53 +0200 |
commit | eccfd443ed78c614c396c542a07673c113f1ecd3 (patch) | |
tree | 297658178b1f24d53c476c9fa62f5a44b9a87d9a /src | |
parent | fc1d61f4cab2260e90fcd468078eaa0d2046f372 (diff) | |
download | colm-eccfd443ed78c614c396c542a07673c113f1ecd3.tar.gz |
allow referencing a tree in reduction actions
syntax is $*N
Diffstat (limited to 'src')
-rw-r--r-- | src/colm.lm | 4 | ||||
-rw-r--r-- | src/compiler.h | 3 | ||||
-rw-r--r-- | src/loadcolm.cc | 12 | ||||
-rw-r--r-- | src/parsetree.h | 1 | ||||
-rw-r--r-- | src/reduce.cc | 67 |
5 files changed, 78 insertions, 9 deletions
diff --git a/src/colm.lm b/src/colm.lm index 2bd4497a..a8e398cf 100644 --- a/src/colm.lm +++ b/src/colm.lm @@ -364,9 +364,11 @@ lex token RED_LHS / '$' . '$' / token RED_RHS_REF / '$' . red_id / token RED_RHS_LOC / '@' . red_id / + token RED_TREE_REF / '$*' . red_id / token RED_RHS_NREF / '$' . ('1' .. '9') . ('0' .. '9')* / token RED_RHS_NLOC / '@' . ('1' .. '9') . ('0' .. '9')* / + token RED_TREE_NREF / '$*' . ('1' .. '9') . ('0' .. '9')* / token red_any / any / end @@ -385,8 +387,10 @@ def host_item | [red_any] | [RED_LHS] | [RED_RHS_REF] +| [RED_TREE_REF] | [RED_RHS_LOC] | [RED_RHS_NREF] +| [RED_TREE_NREF] | [RED_RHS_NLOC] | [RED_OPEN HostItems: host_item* RED_CLOSE] diff --git a/src/compiler.h b/src/compiler.h index 9ad38ee2..ac4a67e6 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -1056,7 +1056,7 @@ struct Compiler void initReductionNeeds( Reduction *reduction ); - void findRhsRefs( bool &lhsUsed, Vector<ProdEl*> &rhsUsed, + void findRhsRefs( bool &lhsUsed, Vector<ProdEl*> &rhsUsed, Vector<ProdEl*> &treeUsed, Vector<ProdEl*> &locUsed, Reduction *reduction, Production *production, const ReduceTextItemList &list ); @@ -1082,6 +1082,7 @@ struct Compiler void writeLhsRef( Production *production, ReduceTextItem *i ); void writeRhsRef( Production *production, ReduceTextItem *i ); + void writeTreeRef( Production *production, ReduceTextItem *i ); void writeRhsLoc( Production *production, ReduceTextItem *i ); void writeHostItemList( Production *production, const ReduceTextItemList &list ); void writeCommitStub(); diff --git a/src/loadcolm.cc b/src/loadcolm.cc index b622f3f2..1b0dba85 100644 --- a/src/loadcolm.cc +++ b/src/loadcolm.cc @@ -2474,6 +2474,12 @@ struct LoadColm rti->txt = item.RED_RHS_REF().text().c_str(); list.append( rti ); } + else if ( item.RED_TREE_REF() != 0 ) { + ReduceTextItem *rti = new ReduceTextItem; + rti->type = ReduceTextItem::TreeRef; + rti->txt = item.RED_TREE_REF().text().c_str(); + list.append( rti ); + } else if ( item.RED_RHS_LOC() != 0 ) { ReduceTextItem *rti = new ReduceTextItem; rti->type = ReduceTextItem::RhsLoc; @@ -2486,6 +2492,12 @@ struct LoadColm rti->n = atoi( item.RED_RHS_NREF().text().c_str() + 1 ); list.append( rti ); } + else if ( item.RED_TREE_NREF() != 0 ) { + ReduceTextItem *rti = new ReduceTextItem; + rti->type = ReduceTextItem::TreeRef; + rti->n = atoi( item.RED_TREE_NREF().text().c_str() + 2 ); + list.append( rti ); + } else if ( item.RED_RHS_NLOC() != 0 ) { ReduceTextItem *rti = new ReduceTextItem; rti->type = ReduceTextItem::RhsLoc; diff --git a/src/parsetree.h b/src/parsetree.h index f81bdbec..599c16b7 100644 --- a/src/parsetree.h +++ b/src/parsetree.h @@ -928,6 +928,7 @@ struct ReduceTextItem enum Type { LhsRef, RhsRef, + TreeRef, RhsLoc, Txt }; diff --git a/src/reduce.cc b/src/reduce.cc index 6e010779..89a95015 100644 --- a/src/reduce.cc +++ b/src/reduce.cc @@ -47,13 +47,14 @@ void Compiler::writeCommitStub() ; } -void Compiler::findRhsRefs( bool &lhsUsed, Vector<ProdEl*> &rhsUsed, +void Compiler::findRhsRefs( bool &lhsUsed, Vector<ProdEl*> &rhsUsed, Vector<ProdEl*> &treeUsed, Vector<ProdEl*> &locUsed, Reduction *reduction, Production *production, const ReduceTextItemList &list ) { ObjectDef *objectDef = production->prodName->objectDef; rhsUsed.setAsNew( production->prodElList->length() ); + treeUsed.setAsNew( production->prodElList->length() ); locUsed.setAsNew( production->prodElList->length() ); for ( ReduceTextItemList::Iter i = list; i.lte(); i++ ) { @@ -61,7 +62,10 @@ void Compiler::findRhsRefs( bool &lhsUsed, Vector<ProdEl*> &rhsUsed, lhsUsed = true; } - if ( i->type == ReduceTextItem::RhsRef || i->type == ReduceTextItem::RhsLoc ) { + if ( i->type == ReduceTextItem::RhsRef || + i->type == ReduceTextItem::RhsLoc || + i->type == ReduceTextItem::TreeRef ) + { if ( i->n > 0 ) { /* Numbered. */ ProdEl *prodEl = production->prodElList->head; @@ -73,6 +77,8 @@ void Compiler::findRhsRefs( bool &lhsUsed, Vector<ProdEl*> &rhsUsed, if ( i->type == ReduceTextItem::RhsLoc ) locUsed[i->n-1] = prodEl; + else if ( i->type == ReduceTextItem::TreeRef ) + treeUsed[i->n-1] = prodEl; else rhsUsed[i->n-1] = prodEl; } @@ -100,9 +106,10 @@ void Compiler::computeNeeded( Reduction *reduction, Production *production, { bool lhsUsed = false; Vector<ProdEl*> rhsUsed; + Vector<ProdEl*> treeUsed; Vector<ProdEl*> locUsed; - findRhsRefs( lhsUsed, rhsUsed, locUsed, reduction, production, list ); + findRhsRefs( lhsUsed, rhsUsed, treeUsed, locUsed, reduction, production, list ); /* Same length, can concurrently walk with one test. */ Vector<ProdEl*>::Iter rhs = rhsUsed; @@ -126,9 +133,10 @@ void Compiler::loadRefs( Reduction *reduction, Production *production, { bool lhsUsed = false; Vector<ProdEl*> rhsUsed; + Vector<ProdEl*> treeUsed; Vector<ProdEl*> locUsed; - findRhsRefs( lhsUsed, rhsUsed, locUsed, reduction, production, list ); + findRhsRefs( lhsUsed, rhsUsed, treeUsed, locUsed, reduction, production, list ); if ( lhsUsed ) { *outStream << " lel_" << production->prodName->fullName << " *_lhs = "; @@ -200,9 +208,8 @@ void Compiler::loadRefs( Reduction *reduction, Production *production, } } - /* In the second pass we load using a tree cursor. This is for token data - * and locations. - */ + /* In the second pass we load using a tree cursor. This is for token/tree + * data and locations. */ useCursor = false; for ( Vector<ProdEl*>::Iter rhs = rhsUsed; rhs.lte(); rhs++ ) { @@ -213,6 +220,12 @@ void Compiler::loadRefs( Reduction *reduction, Production *production, break; } } + for ( Vector<ProdEl*>::Iter rhs = treeUsed; rhs.lte(); rhs++ ) { + if ( *rhs != 0 ) { + useCursor = true; + break; + } + } for ( Vector<ProdEl*>::Iter loc = locUsed; loc.lte(); loc++ ) { if ( *loc != 0 ) { useCursor = true; @@ -234,12 +247,12 @@ void Compiler::loadRefs( Reduction *reduction, Production *production, /* Same length, can concurrently walk with one test. */ Vector<ProdEl*>::Iter rhs = rhsUsed; + Vector<ProdEl*>::Iter tree = treeUsed; Vector<ProdEl*>::Iter loc = locUsed; for ( ; rhs.lte(); rhs++, loc++ ) { ProdEl *prodEl = *rhs; - if ( prodEl != 0 ) { if ( prodEl->production == production ) { if ( prodEl->langEl->type == LangEl::Term ) { @@ -262,7 +275,20 @@ void Compiler::loadRefs( Reduction *reduction, Production *production, } } } + } + + ProdEl *treeEl = *tree; + if ( treeEl != 0 ) { + if ( treeEl->production == production ) { + while ( cursorPos < rhs.pos() ) { + *outStream << + " _tree_cursor = _tree_cursor->next;\n"; + cursorPos += 1; + } + *outStream << " colm_tree *_tree" << rhs.pos() << " = "; + *outStream << "_tree_cursor->tree;\n"; + } } ProdEl *locEl = *loc; @@ -313,6 +339,28 @@ void Compiler::writeRhsRef( Production *production, ReduceTextItem *i ) } } +void Compiler::writeTreeRef( Production *production, ReduceTextItem *i ) +{ + if ( i->n > 0 ) { + *outStream << "_tree" << ( i->n - 1 ); + } + else { + ObjectDef *objectDef = production->prodName->objectDef; + String name( i->txt.data + 1, i->txt.length() - 1 ); + + /* Find the field in the rhsVal using capture field. */ + ObjectField *field = objectDef->rootScope->findField( name ); + if ( field != 0 ) { + for ( Vector<RhsVal>::Iter r = field->rhsVal; + r.lte(); r++ ) + { + if ( r->prodEl->production == production ) + *outStream << "_tree" << r->prodEl->pos; + } + } + } +} + void Compiler::writeRhsLoc( Production *production, ReduceTextItem *i ) { if ( i->n > 0 ) { @@ -351,6 +399,9 @@ void Compiler::writeHostItemList( Production *production, case ReduceTextItem::RhsRef: writeRhsRef( production, i ); break; + case ReduceTextItem::TreeRef: + writeTreeRef( production, i ); + break; case ReduceTextItem::RhsLoc: writeRhsLoc( production, i ); break; |