From 2fcb7bac46eb4b9e1ed7f133dea62370867a0d0e Mon Sep 17 00:00:00 2001 From: Adrian Thurston Date: Tue, 25 Jul 2017 19:36:21 -0400 Subject: added a reducer that can read the streaming postfix format --- src/compiler.h | 2 +- src/pdacodegen.cc | 2 + src/print.c | 67 ++++++++++---- src/program.h | 1 + src/reduce.cc | 257 +++++++++++++++++++++++++++++++++++++++++++++++------- 5 files changed, 281 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/compiler.h b/src/compiler.h index c8f0ab79..d3ebc9f1 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -1036,7 +1036,7 @@ struct Compiler void initReductionNeeds( Reduction *reduction ); void loadRefs( Reduction *reduction, Production *production, - const ReduceTextItemList &list ); + const ReduceTextItemList &list, bool read ); void writeHostCall(); void writeNeeds(); diff --git a/src/pdacodegen.cc b/src/pdacodegen.cc index 6e16c474..2a088f89 100644 --- a/src/pdacodegen.cc +++ b/src/pdacodegen.cc @@ -450,6 +450,7 @@ void PdaCodeGen::writeRuntimeData( colm_sections *runtimeData, struct pda_tables "struct pda_run *pda_run, int id );\n" "int " << objectName << "_reducer_need_ign( program_t *prg, " "struct pda_run *pda_run );\n" + "void " << objectName << "_read_reduce( program_t *prg, int reducer );\n" "\n"; out << @@ -519,6 +520,7 @@ void PdaCodeGen::writeRuntimeData( colm_sections *runtimeData, struct pda_tables " &" << objectName << "_init_need,\n" " &" << objectName << "_reducer_need_tok,\n" " &" << objectName << "_reducer_need_ign,\n" + " &" << objectName << "_read_reduce,\n" "};\n" "\n"; } diff --git a/src/print.c b/src/print.c index 46c8fe42..f424c314 100644 --- a/src/print.c +++ b/src/print.c @@ -639,26 +639,44 @@ static void postfix_term( program_t *prg, tree_t **sp, args->out( args, "s\n", 2 ); } else if ( 0 < kid->tree->id && kid->tree->id < prg->rtd->first_non_term_id && - kid->tree->id != LEL_ID_IGNORE && - kid->tree->tokdata != 0 && - string_length( kid->tree->tokdata ) > 0 ) + kid->tree->id != LEL_ID_IGNORE //&& + //kid->tree->tokdata != 0 && + //string_length( kid->tree->tokdata ) > 0 ) + ) { char buf[512]; struct lang_el_info *lel_info = prg->rtd->lel_info; const char *name = lel_info[kid->tree->id].xml_tag; - struct colm_data *tokdata = kid->tree->tokdata; - struct colm_location *loc = tokdata->location; - - sprintf( buf, "%ld %ld %ld", loc->line, loc->column, loc->byte ); args->out( args, "t ", 2 ); args->out( args, name, strlen( name ) ); - args->out( args, " ", 1 ); + + /* id. */ + sprintf( buf, " %d", kid->tree->id ); args->out( args, buf, strlen( buf ) ); - args->out( args, " ", 1 ); - postfix_term_data( args, - string_data( tokdata ), string_length( tokdata ) ); + /* location. */ + if ( kid->tree->tokdata == 0 ) { + args->out( args, " 0 0 0 -", 8 ); + } + else { + struct colm_data *tokdata = kid->tree->tokdata; + struct colm_location *loc = tokdata->location; + if ( loc == 0 ) { + args->out( args, " 0 0 0 ", 7 ); + } + else { + sprintf( buf, " %ld %ld %ld ", loc->line, loc->column, loc->byte ); + args->out( args, buf, strlen( buf ) ); + } + + if ( string_length( tokdata ) == 0 ) { + args->out( args, "-", 1 ); + } + else { + postfix_term_data( args, string_data( tokdata ), string_length( tokdata ) ); + } + } args->out( args, "\n", 1 ); } @@ -674,15 +692,30 @@ static void postfix_close( program_t *prg, tree_t **sp, if ( kid->tree->id >= prg->rtd->first_non_term_id ) { char buf[512]; struct lang_el_info *lel_info = prg->rtd->lel_info; - const char *name = lel_info[kid->tree->id].xml_tag; - sprintf( buf, "%ld", kid->tree->prod_num ); - args->out( args, "r ", 2 ); args->out( args, name, strlen( name ) ); - args->out( args, " ", 1 ); + + /* id. */ + sprintf( buf, " %d", kid->tree->id ); + args->out( args, buf, strlen( buf ) ); + + /* Production number. */ + sprintf( buf, " %d", kid->tree->prod_num ); args->out( args, buf, strlen( buf ) ); + + /* Child count. */ + int children = 0; + kid_t *child = tree_child( prg, kid->tree ); + while ( child != 0 ) { + child = child->next; + children += 1; + } + + sprintf( buf, " %d", children ); + args->out( args, buf, strlen( buf ) ); + args->out( args, "\n", 1 ); } } @@ -691,7 +724,7 @@ void colm_postfix_tree_collect( program_t *prg, tree_t **sp, StrCollect *collect, tree_t *tree, int trim ) { struct colm_print_args print_args = { - collect, true, false, false, &append_collect, + collect, false, false, false, &append_collect, &postfix_open, &postfix_term, &postfix_close }; @@ -702,7 +735,7 @@ void colm_postfix_tree_file( program_t *prg, tree_t **sp, struct stream_impl *im tree_t *tree, int trim ) { struct colm_print_args print_args = { - impl, true, false, false, &append_file, + impl, false, false, false, &append_file, &postfix_open, &postfix_term, &postfix_close }; diff --git a/src/program.h b/src/program.h index 1dbff78d..e3f747e0 100644 --- a/src/program.h +++ b/src/program.h @@ -112,6 +112,7 @@ struct colm_sections void (*init_need)(); int (*reducer_need_tok)( program_t *prg, struct pda_run *pda_run, int id ); int (*reducer_need_ign)( program_t *prg, struct pda_run *pda_run ); + void (*read_reduce)( program_t *prg, int reducer ); }; struct heap_list diff --git a/src/reduce.cc b/src/reduce.cc index 1c8dfb47..953dc652 100644 --- a/src/reduce.cc +++ b/src/reduce.cc @@ -42,12 +42,13 @@ void Compiler::writeCommitStub() "struct pda_run *pda_run, int id ) { return COLM_RN_BOTH; }\n" "int " << objectName << "_reducer_need_ign( program_t *prg, " "struct pda_run *pda_run ) { return COLM_RN_BOTH; }\n" - "\n"; + "\n" + "void " << objectName << "_read_reduce( program_t *prg, int reducer ) {}\n" ; } void Compiler::loadRefs( Reduction *reduction, Production *production, - const ReduceTextItemList &list ) + const ReduceTextItemList &list, bool read ) { ObjectDef *objectDef = production->prodName->objectDef; Vector rhsUsed; @@ -93,10 +94,16 @@ void Compiler::loadRefs( Reduction *reduction, Production *production, } if ( lhsUsed ) { - *outStream << - " lel_" << production->prodName->fullName << " *_lhs = " - "&((commit_reduce_union*)(lel+1))->" << - production->prodName->fullName << ";\n"; + *outStream << " lel_" << production->prodName->fullName << " *_lhs = "; + + if ( read ) { + *outStream << + "&node->u." << production->prodName->fullName << ";\n"; + } + else { + *outStream << + "&((commit_reduce_union*)(lel+1))->" << production->prodName->fullName << ";\n"; + } } /* @@ -116,8 +123,14 @@ void Compiler::loadRefs( Reduction *reduction, Production *production, if ( useCursor ) { int cursorPos = 0; - *outStream << - " struct colm_parse_tree *_pt_cursor = lel->child;\n"; + if ( read ) { + *outStream << + " struct read_reduce_node *_pt_cursor = node->child;\n"; + } + else { + *outStream << + " struct colm_parse_tree *_pt_cursor = lel->child;\n"; + } /* Same length, can concurrently walk with one test. */ Vector::Iter rhs = rhsUsed; @@ -136,10 +149,14 @@ void Compiler::loadRefs( Reduction *reduction, Production *production, if ( prodEl->production == production ) { if ( prodEl->langEl->type != LangEl::Term ) { *outStream << - "lel_" << prodEl->langEl->fullName << " *" - "_rhs" << rhs.pos() << " = &((commit_reduce_union*)" - "(_pt_cursor+1))->" << - prodEl->langEl->fullName << ";\n"; + "lel_" << prodEl->langEl->fullName << " *" "_rhs" << rhs.pos() << " = "; + + if ( read ) { + *outStream << "&_pt_cursor->u." << prodEl->langEl->fullName << ";\n"; + } + else { + *outStream << "&((commit_reduce_union*)(_pt_cursor+1))->" << prodEl->langEl->fullName << ";\n"; + } } } @@ -170,8 +187,14 @@ void Compiler::loadRefs( Reduction *reduction, Production *production, if ( useCursor ) { int cursorPos = 0; - *outStream << - " kid_t *_tree_cursor = kid->tree->child;\n"; + if ( read ) { + *outStream << + " read_reduce_node *_tree_cursor = node->child;\n"; + } + else { + *outStream << + " kid_t *_tree_cursor = kid->tree->child;\n"; + } /* Same length, can concurrently walk with one test. */ Vector::Iter rhs = rhsUsed; @@ -185,14 +208,22 @@ void Compiler::loadRefs( Reduction *reduction, Production *production, if ( prodEl->production == production ) { if ( prodEl->langEl->type == LangEl::Term ) { - while ( cursorPos < rhs.pos() ) { - *outStream << - " _tree_cursor = _tree_cursor->next;\n"; - cursorPos += 1; - } - *outStream << - " colm_data *_rhs" << rhs.pos() << " = " - "_tree_cursor->tree->tokdata;\n"; + while ( cursorPos < rhs.pos() ) { + *outStream << + " _tree_cursor = _tree_cursor->next;\n"; + cursorPos += 1; + } + + *outStream << " colm_data *_rhs" << rhs.pos() << " = "; + + if ( read ) { + *outStream << + "&_tree_cursor->data;\n"; + } + else { + *outStream << + "_tree_cursor->tree->tokdata;\n"; + } reduction->needData[prodEl->langEl->id] = true; } @@ -204,15 +235,22 @@ void Compiler::loadRefs( Reduction *reduction, Production *production, if ( locEl != 0 ) { if ( locEl->production == production ) { - while ( cursorPos < rhs.pos() ) { - *outStream << - " _tree_cursor = _tree_cursor->next;\n"; - cursorPos += 1; - } + while ( cursorPos < rhs.pos() ) { + *outStream << + " _tree_cursor = _tree_cursor->next;\n"; + cursorPos += 1; + } *outStream << - " colm_location *_loc" << loc.pos() << " = " + " colm_location *_loc" << loc.pos() << " = "; + + if ( read ) { + *outStream << "&_tree_cursor->loc;\n"; + } + else { + *outStream << "colm_find_location( prg, _tree_cursor->tree );\n"; + } reduction->needLoc[locEl->langEl->id] = true; } @@ -546,10 +584,10 @@ void Compiler::writeCommit() *outStream << " if ( kid->tree->prod_num == " << prodNum << " ) {\n"; - loadRefs( reduction, action->production, action->itemList ); + loadRefs( reduction, action->production, action->itemList, false ); *outStream << - "#line " << action->loc.line << "\"" << action->loc.fileName << "\"\n"; + "#line " << action->loc.line << " \"" << action->loc.fileName << "\"\n"; writeHostItemList( action->production, action->itemList ); @@ -584,4 +622,163 @@ void Compiler::writeCommit() } writeNeeds(); + +/* READ REDUCE */ + + *outStream << + "extern \"C\" void " << objectName << "_read_reduce( program_t *prg, int reducer )\n" + "{\n" + " switch ( reducer ) {\n"; + + for ( ReductionVect::Iter r = rootNamespace->reductions; r.lte(); r++ ) { + Reduction *reduction = *r; + *outStream << + " case " << reduction->id << ":\n" + " ((" << reduction->name << "*)prg->red_ctx)->read_reduce_forward( prg );\n" + " break;\n"; + } + + *outStream << + " }\n" + "}\n" + "\n"; + + for ( ReductionVect::Iter r = rootNamespace->reductions; r.lte(); r++ ) { + Reduction *reduction = *r; + initReductionNeeds( reduction ); + + *outStream << + "struct read_reduce_node\n" + "{\n" + " std::string name;\n" + " int id;\n" + " int prod_num;\n" + " colm_location loc;\n" + " colm_data data;\n" + " commit_reduce_union u;\n" + " read_reduce_node *next;\n" + " read_reduce_node *child;\n" + "};\n" + "\n" + "void " << reduction->name << "::read_reduce_forward( program_t *prg )\n" + "{\n" + " std::ifstream in( \"postfix.txt\" );\n" + " std::string type, tok, text;\n" + " long _id, line, column, byte, prod_num, children;\n" + " read_reduce_node sentinal;\n" + " sentinal.next = 0;\n" + " read_reduce_node *stack = &sentinal, *last = 0;\n" + " while ( in >> type ) {\n" + " /* read. */\n" + " if ( type == \"t\" ) {\n" + " in >> tok >> _id >> line >> column >> byte >> text;\n" + " read_reduce_node *node = new read_reduce_node;\n" + " node->name = tok;\n" + " node->id = _id;\n" + " node->loc.name = \"<>\";\n" + " node->loc.line = line;\n" + " node->loc.column = column;\n" + " node->loc.byte = byte;\n" + " node->data.data = strdup( text.c_str() );\n" + " node->data.length = text.size();\n" + "\n" + " node->next = stack;\n" + " node->child = 0;\n" + " stack = node;\n" + " }\n" + " else if ( type == \"r\" ) {\n" + " in >> tok >> _id >> prod_num >> children;\n" + " std::cout << \"reducing: \" << tok << std::endl;\n" + " read_reduce_node *node = new read_reduce_node;\n" + " memset( &node->loc, 0, sizeof(colm_location) );\n" + " memset( &node->data, 0, sizeof(colm_data) );\n" + " node->name = tok;\n" + " node->id = _id;\n" + " node->prod_num = prod_num;\n" + " node->child = 0;\n" + " while ( children-- > 0 ) {\n" + " last = stack;\n" + " stack = stack->next;\n" + " last->next = node->child;\n" + " node->child = last;\n" + " }\n" + "\n" + " node->next = stack;\n" + " stack = node;\n" + "\n" + " { switch ( node->id ) {\n"; + + /* Populate a vector with the reduce actions. */ + Vector actions; + actions.setAsNew( reduction->reduceActions.length() ); + long pos = 0; + for ( ReduceActionList::Iter rdi = reduction->reduceActions; rdi.lte(); rdi++ ) + actions[pos++] = rdi; + + /* Sort it by lhs id, then prod num. */ + MergeSort sortActions; + sortActions.sort( actions.data, actions.length() ); + + ReduceAction *last = 0; + + for ( Vector::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 ( node->prod_num == " << prodNum << " ) {\n"; + + loadRefs( reduction, action->production, action->itemList, true ); + + *outStream << + "#line " << action->loc.line << "\"" << action->loc.fileName << "\"\n"; + + writeHostItemList( action->production, action->itemList ); + + *outStream << + " }\n"; + + last = action; + } + + if ( last != 0 ) { + *outStream << + " break;\n" + " }\n"; + } + + + *outStream << + " } }\n" + " /* delete the children */\n" + " last = node->child;\n" + " while ( last != 0 ) {\n" + " read_reduce_node *next = last->next;\n" + " delete last;\n" + " last = next;\n" + " }\n" + " }\n" + " }\n" + "}\n" + "\n"; + } } -- cgit v1.2.1