diff options
-rw-r--r-- | src/colm.lm | 7 | ||||
-rw-r--r-- | src/compiler.h | 3 | ||||
-rw-r--r-- | src/loadcolm.cc | 23 | ||||
-rw-r--r-- | src/parsetree.h | 3 | ||||
-rw-r--r-- | src/reduce.cc | 137 |
5 files changed, 150 insertions, 23 deletions
diff --git a/src/colm.lm b/src/colm.lm index 74e83bf5..a74e53c9 100644 --- a/src/colm.lm +++ b/src/colm.lm @@ -361,7 +361,8 @@ lex / token RED_LHS / '$' . '$' / - token RED_RHS / '$' . red_id / + token RED_RHS_REF / '$' . red_id / + token RED_RHS_LOC / '@' . red_id / token red_any / any / end @@ -379,7 +380,9 @@ def host_item | [red_ws] | [red_any] | [RED_LHS] -| [RED_RHS] +| [RED_RHS_REF] +| [RED_RHS_LOC] +| [RED_OPEN HostItems: host_item* RED_CLOSE] def reduction_item [red_nonterm] :NonTerm commit diff --git a/src/compiler.h b/src/compiler.h index 5bc58e2b..288b3cf1 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -1013,8 +1013,9 @@ struct Compiler void writeHostCall(); void writeCommit(); - void writeRhsRef( Production *production, ReduceTextItem *i ); void writeLhsRef( Production *production, ReduceTextItem *i ); + void writeRhsRef( 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 7dd21141..4829d519 100644 --- a/src/loadcolm.cc +++ b/src/loadcolm.cc @@ -2353,12 +2353,31 @@ struct LoadColm rti->type = ReduceTextItem::LhsRef; list.append( rti ); } - else if ( item.RED_RHS() != 0 ) { + else if ( item.RED_RHS_REF() != 0 ) { ReduceTextItem *rti = new ReduceTextItem; rti->type = ReduceTextItem::RhsRef; - rti->txt = item.RED_RHS().text().c_str(); + rti->txt = item.RED_RHS_REF().text().c_str(); list.append( rti ); } + else if ( item.RED_RHS_LOC() != 0 ) { + ReduceTextItem *rti = new ReduceTextItem; + rti->type = ReduceTextItem::RhsLoc; + rti->txt = item.RED_RHS_LOC().text().c_str(); + list.append( rti ); + } + else if ( item.RED_OPEN() != 0 ) { + ReduceTextItem *open = new ReduceTextItem; + open->type = ReduceTextItem::Txt; + open->txt = "{"; + list.append( open ); + + walkRedItemList( item.HostItems(), list ); + + ReduceTextItem *close = new ReduceTextItem; + close->type = ReduceTextItem::Txt; + close->txt = "}"; + list.append( close ); + } else { if ( list.length() > 0 && list.tail->type == ReduceTextItem::Txt ) { std::string txt = item.text(); diff --git a/src/parsetree.h b/src/parsetree.h index 9a7ddb4a..fc53be89 100644 --- a/src/parsetree.h +++ b/src/parsetree.h @@ -922,6 +922,7 @@ struct ReduceTextItem enum Type { LhsRef, RhsRef, + RhsLoc, Txt }; @@ -972,6 +973,8 @@ struct ReduceAction typedef DList<ReduceAction> ReduceActionList; typedef DList<ReduceNonTerm> ReduceNonTermList; +typedef Vector<ReduceAction*> ReduceActionVect; + struct Reduction { Reduction( const InputLoc &loc, String name ) diff --git a/src/reduce.cc b/src/reduce.cc index 3a547c46..a22410cc 100644 --- a/src/reduce.cc +++ b/src/reduce.cc @@ -58,7 +58,9 @@ void Compiler::loadRefs( Production *production, const ReduceTextItemList &list { ObjectDef *objectDef = production->prodName->objectDef; Vector<ProdEl*> rhsUsed; + Vector<ProdEl*> locUsed; rhsUsed.setAsNew( production->prodElList->length() ); + locUsed.setAsNew( production->prodElList->length() ); bool lhsUsed = false; for ( ReduceTextItemList::Iter i = list; i.lte(); i++ ) { @@ -66,13 +68,17 @@ void Compiler::loadRefs( Production *production, const ReduceTextItemList &list lhsUsed = true; } - if ( i->type == ReduceTextItem::RhsRef ) { + if ( i->type == ReduceTextItem::RhsRef || i->type == ReduceTextItem::RhsLoc ) { String name( i->txt.data + 1, i->txt.length() - 1 ); ObjectField *field = objectDef->rootScope->findField( name ); if ( field != 0 ) { for ( Vector<RhsVal>::Iter r = field->rhsVal; r.lte(); r++ ) { - if ( r->prodEl->production == production ) - rhsUsed[r->prodEl->pos] = r->prodEl; + if ( r->prodEl->production == production ) { + if ( i->type == ReduceTextItem::RhsLoc ) + locUsed[r->prodEl->pos] = r->prodEl; + else + rhsUsed[r->prodEl->pos] = r->prodEl; + } } } } @@ -93,20 +99,31 @@ void Compiler::loadRefs( Production *production, const ReduceTextItemList &list *outStream << " colm_data *_rhs" << rhs.pos() << " = " "get_rhs_el_kid( prg, kid->tree, " - << prodEl->pos << ")->tree->tokdata;\n"; + << prodEl->pos << " )->tree->tokdata;\n"; } else { *outStream << "lel_" << prodEl->langEl->fullName << " *" "_rhs" << rhs.pos() << " = &((commit_reduce_union*)" "(get_rhs_parse_tree( prg, lel, " << - prodEl->pos << ")+1))->" << + prodEl->pos << " )+1))->" << prodEl->langEl->fullName << ";\n"; } } } } + for ( Vector<ProdEl*>::Iter loc = locUsed; loc.lte(); loc++ ) { + ProdEl *prodEl = *loc; + if ( prodEl != 0 ) { + if ( prodEl->production == production ) { + *outStream << + " colm_location *_loc" << loc.pos() << " = " + "colm_find_location( prg, get_rhs_el_kid( prg, kid->tree, " << + prodEl->pos << " )->tree );\n"; + } + } + } } void Compiler::writeRhsRef( Production *production, ReduceTextItem *i ) @@ -126,6 +143,23 @@ void Compiler::writeRhsRef( Production *production, ReduceTextItem *i ) } } +void Compiler::writeRhsLoc( Production *production, ReduceTextItem *i ) +{ + 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 << "_loc" << r->prodEl->pos; + } + } +} + void Compiler::writeLhsRef( Production *production, ReduceTextItem *i ) { *outStream << "_lhs"; @@ -136,11 +170,14 @@ void Compiler::writeHostItemList( Production *production, { for ( ReduceTextItemList::Iter i = list; i.lte(); i++ ) { switch ( i->type ) { + case ReduceTextItem::LhsRef: + writeLhsRef( production, i ); + break; case ReduceTextItem::RhsRef: writeRhsRef( production, i ); break; - case ReduceTextItem::LhsRef: - writeLhsRef( production, i ); + case ReduceTextItem::RhsLoc: + writeRhsLoc( production, i ); break; case ReduceTextItem::Txt: *outStream << i->txt; @@ -149,13 +186,30 @@ void Compiler::writeHostItemList( Production *production, } } +/* For sorting according to prod name id, then by prod num. */ +struct CmpReduceAction +{ + static int compare( const ReduceAction *ra1 , const ReduceAction *ra2 ) + { + if ( ra1->production->prodName->id < ra2->production->prodName->id ) + return -1; + else if ( ra1->production->prodName->id > ra2->production->prodName->id ) + return 1; + else { + if ( ra1->production->prodNum < ra2->production->prodNum ) + return -1; + else if ( ra1->production->prodNum < ra2->production->prodNum ) + return 1; + } + return 0; + } +}; + void Compiler::writeCommit() { *outStream << "#include <colm/pdarun.h>\n" - "#include <colm/debug.h>\n" "#include <colm/bytecode.h>\n" - "#include <colm/config.h>\n" "#include <colm/defs.h>\n" "#include <colm/input.h>\n" "#include <colm/tree.h>\n" @@ -167,7 +221,13 @@ void Compiler::writeCommit() "#include <string.h>\n" "#include <assert.h>\n" "\n" - "#include <iostream>\n"; + "#include <iostream>\n" + "\n" + "#include \"reducer.h\"\n" + "\n" + "Reducer *reducer;\n" + "\n" + ; for ( ReductionVect::Iter r = rootNamespace->reductions; r.lte(); r++ ) { for ( ReduceNonTermList::Iter rdi = (*r)->reduceNonTerms; rdi.lte(); rdi++ ) { @@ -205,6 +265,10 @@ void Compiler::writeCommit() "\n" "void commit_reduce_forward( program_t *prg, tree_t **root,\n" " struct pda_run *pda_run, parse_tree_t *pt )\n" + "{ reducer->commit_reduce_forward( prg, root, pda_run, pt ); }\n" + "\n" + "void Reducer::commit_reduce_forward( program_t *prg, tree_t **root,\n" + " struct pda_run *pda_run, parse_tree_t *pt )\n" "{\n" " tree_t **sp = root;\n" "\n" @@ -236,19 +300,56 @@ void Compiler::writeCommit() " switch ( kid->tree->id ) {\n"; for ( ReductionVect::Iter r = rootNamespace->reductions; r.lte(); r++ ) { - for ( ReduceActionList::Iter rdi = (*r)->reduceActions; rdi.lte(); rdi++ ) { - int lelId = rdi->production->prodName->id; - int prodNum = rdi->production->prodNum; + /* Populate a vector with the reduce actions. */ + Vector<ReduceAction*> actions; + actions.setAsNew( (*r)->reduceActions.length() ); + long pos = 0; + for ( ReduceActionList::Iter rdi = (*r)->reduceActions; rdi.lte(); rdi++ ) + actions[pos++] = rdi; - *outStream << - " case " << lelId << ": {\n" + /* Sort it by lhs id, then prod num. */ + MergeSort<ReduceAction*, CmpReduceAction> sortActions; + sortActions.sort( actions.data, actions.length() ); + + ReduceAction *last = 0; + + for ( Vector<ReduceAction*>::Iter rdi = actions; rdi.lte(); rdi++ ) { + ReduceAction *action = *rdi; + int lelId = action->production->prodName->id; + int prodNum = action->production->prodNum; + + /* Maybe close off the last prod. */ + if ( last != 0 && + last->production->prodName != action->production->prodName ) + { + *outStream << + " break;\n" + " }\n"; + + } + + /* Maybe open a new prod. */ + if ( last == 0 || + last->production->prodName != action->production->prodName ) + { + *outStream << + " case " << lelId << ": {\n"; + } + + *outStream << " if ( kid->tree->prod_num == " << prodNum << " ) {\n"; - loadRefs( rdi->production, rdi->itemList ); - writeHostItemList( rdi->production, rdi->itemList ); + loadRefs( action->production, action->itemList ); + writeHostItemList( action->production, action->itemList ); + + *outStream << + " }\n"; + + last = action; + } + if ( last != 0 ) { *outStream << - " }\n" " break;\n" " }\n"; } |