diff options
Diffstat (limited to 'colm')
-rw-r--r-- | colm/colm.h | 2 | ||||
-rw-r--r-- | colm/colm.lm | 76 | ||||
-rw-r--r-- | colm/compiler.cc | 15 | ||||
-rw-r--r-- | colm/compiler.h | 5 | ||||
-rw-r--r-- | colm/consinit.cc | 12 | ||||
-rw-r--r-- | colm/exports.cc | 39 | ||||
-rw-r--r-- | colm/loadfinal.cc | 2 | ||||
-rw-r--r-- | colm/loadinit.cc | 2 | ||||
-rw-r--r-- | colm/parsetree.h | 3 | ||||
-rw-r--r-- | colm/pdabuild.cc | 1 | ||||
-rw-r--r-- | colm/prog.lm | 22 | ||||
-rw-r--r-- | colm/resolve.cc | 9 | ||||
-rw-r--r-- | colm/tree.c | 24 |
13 files changed, 142 insertions, 70 deletions
diff --git a/colm/colm.h b/colm/colm.h index 55368840..5091d27e 100644 --- a/colm/colm.h +++ b/colm/colm.h @@ -95,6 +95,8 @@ struct colm_tree *colm_get_attr( struct colm_tree *tree, long pos ); struct colm_tree *colm_get_global( struct colm_program *prg, long pos ); struct colm_tree *colm_get_repeat_next( struct colm_tree *tree ); struct colm_tree *colm_get_repeat_val( struct colm_tree *tree ); +struct colm_tree *colm_get_left_repeat_next( struct colm_tree *tree ); +struct colm_tree *colm_get_left_repeat_val( struct colm_tree *tree ); struct colm_location *colm_find_location( struct colm_program *prg, struct colm_tree *tree ); /* Debug realms. To turn on, pass to colm_set_debug before invocation. */ diff --git a/colm/colm.lm b/colm/colm.lm index efbd7a65..4ebe11b8 100644 --- a/colm/colm.lm +++ b/colm/colm.lm @@ -206,7 +206,7 @@ lex end def start - [RootItemList: root_item*] + [RootItemList: root_item<*] def root_item [rl_def] :Rl commit @@ -231,7 +231,7 @@ def root_item | [reduction_def] :Reduction commit def _include - [INCLUDE SQ SqConsDataList: sq_cons_data* sq_lit_term] + [INCLUDE SQ SqConsDataList: sq_cons_data<* sq_lit_term] def precedence_def [pred_type pred_token_list] @@ -319,7 +319,7 @@ def struct_key [STRUCT] | [CONTEXT] def struct_def - [struct_key id ItemList: struct_item* END] + [struct_key id ItemList: struct_item<* END] def literal_keyword [LITERAL] @@ -344,7 +344,7 @@ def no_ignore_right | [] def reduction_def - [REDUCTION id ItemList: reduction_item* END] + [REDUCTION id ItemList: reduction_item<* END] lex token RED_OPEN / '{' / @@ -382,10 +382,10 @@ lex end def red_nonterm - [type_ref RED_OPEN HostItems: host_item* RED_CLOSE] + [type_ref RED_OPEN HostItems: host_item<* RED_CLOSE] def red_action - [type_ref COLON id RED_OPEN HostItems: host_item* RED_CLOSE] + [type_ref COLON id RED_OPEN HostItems: host_item<* RED_CLOSE] def host_item [red_id] @@ -400,14 +400,14 @@ def host_item | [RED_RHS_NREF] | [RED_TREE_NREF] | [RED_RHS_NLOC] -| [RED_OPEN HostItems: host_item* RED_CLOSE] +| [RED_OPEN HostItems: host_item<* RED_CLOSE] def reduction_item [red_nonterm] :NonTerm commit | [red_action] :Action commit def namespace_def - [NAMESPACE id ItemList: namespace_item* END] + [NAMESPACE id ItemList: namespace_item<* END] def namespace_item [rl_def] :Rl commit @@ -437,12 +437,12 @@ def opt_reduce_first def cfl_def [DEF id - VarDefList: var_def* + VarDefList: var_def<* opt_reduce_first prod_list] def region_def - [LEX RootItemList: root_item* END] + [LEX RootItemList: root_item<* END] def rl_def [RL id LEX_FSLASH lex_expr LEX_FSLASH] @@ -452,7 +452,7 @@ def opt_lex_expr | [] def token_def - [TOKEN id VarDefList: var_def* + [TOKEN id VarDefList: var_def<* no_ignore_left LEX_FSLASH opt_lex_expr LEX_FSLASH no_ignore_right @@ -583,7 +583,7 @@ def opt_require_stmt | [] :Base def lang_stmt_list - [StmtList: statement* opt_require_stmt] + [StmtList: statement<* opt_require_stmt] def opt_def_init [EQUALS code_expr] :Init @@ -680,7 +680,7 @@ def opt_capture | [] def opt_field_init - [POPEN FieldInitList: field_init* PCLOSE] :Init + [POPEN FieldInitList: field_init<* PCLOSE] :Init | [] :Base def field_init @@ -698,7 +698,7 @@ def stmt_or_factor | [MAKE_TOKEN POPEN call_arg_list PCLOSE] :MakeToken | [CONS opt_capture type_ref opt_field_init constructor] :Cons | [MATCH var_ref pattern] :Match -| [NEW opt_capture type_ref POPEN FieldInitList: field_init* PCLOSE] :New +| [NEW opt_capture type_ref POPEN FieldInitList: field_init<* PCLOSE] :New # # Pattern @@ -724,19 +724,19 @@ def pattern_el_lel def pattern_el [opt_label pattern_el_lel] :PatternEl -| [DQ LitpatElList: litpat_el* dq_lit_term] :Dq -| [SQ SqConsDataList: sq_cons_data* sq_lit_term] :Sq +| [DQ LitpatElList: litpat_el<* dq_lit_term] :Dq +| [SQ SqConsDataList: sq_cons_data<* sq_lit_term] :Sq | [TILDE opt_tilde_data TILDE_NL] :Tilde def litpat_el [lit_dq_data] :ConsData -| [LIT_SQOPEN PatternElList: pattern_el* LIT_SQCLOSE] :SubList +| [LIT_SQOPEN PatternElList: pattern_el<* LIT_SQCLOSE] :SubList def pattern_top_el - [DQ LitpatElList: litpat_el* dq_lit_term] :Dq -| [SQ SqConsDataList: sq_cons_data* sq_lit_term] :Sq + [DQ LitpatElList: litpat_el<* dq_lit_term] :Dq +| [SQ SqConsDataList: sq_cons_data<* sq_lit_term] :Sq | [TILDE opt_tilde_data TILDE_NL] :Tilde -| [SQOPEN PatternElList: pattern_el* SQCLOSE] :SubList +| [SQOPEN PatternElList: pattern_el<* SQCLOSE] :SubList def pattern_list [pattern_top_el] :Base @@ -755,20 +755,20 @@ def E4 [] def cons_el [E1 region_qual backtick_lit] :Lit -| [E1 DQ LitConsElList: lit_cons_el* dq_lit_term] :Dq -| [E1 SQ SqConsDataList: sq_cons_data* sq_lit_term] :Sq +| [E1 DQ LitConsElList: lit_cons_el<* dq_lit_term] :Dq +| [E1 SQ SqConsDataList: sq_cons_data<* sq_lit_term] :Sq | [E1 TILDE opt_tilde_data TILDE_NL] :Tilde | [E2 code_expr] :CodeExpr def lit_cons_el [lit_dq_data] :ConsData -| [LIT_SQOPEN ConsElList: cons_el* LIT_SQCLOSE] :SubList +| [LIT_SQOPEN ConsElList: cons_el<* LIT_SQCLOSE] :SubList def cons_top_el - [DQ LitConsElList: lit_cons_el* dq_lit_term] :Dq -| [SQ SqConsDataList: sq_cons_data* sq_lit_term] :Sq + [DQ LitConsElList: lit_cons_el<* dq_lit_term] :Dq +| [SQ SqConsDataList: sq_cons_data<* sq_lit_term] :Sq | [TILDE opt_tilde_data TILDE_NL] :Tilde -| [SQOPEN ConsElList: cons_el* SQCLOSE] :SubList +| [SQOPEN ConsElList: cons_el<* SQCLOSE] :SubList def cons_list [cons_top_el] :Base @@ -781,20 +781,20 @@ def constructor # def accum_el - [E1 DQ LitAccumElList: lit_accum_el* dq_lit_term] :Dq -| [E1 SQ SqConsDataList: sq_cons_data* sq_lit_term] :Sq + [E1 DQ LitAccumElList: lit_accum_el<* dq_lit_term] :Dq +| [E1 SQ SqConsDataList: sq_cons_data<* sq_lit_term] :Sq | [E1 TILDE opt_tilde_data TILDE_NL] :Tilde | [E2 code_expr] :CodeExpr def lit_accum_el [lit_dq_data] :ConsData -| [LIT_SQOPEN AccumElList: accum_el* LIT_SQCLOSE] :SubList +| [LIT_SQOPEN AccumElList: accum_el<* LIT_SQCLOSE] :SubList def accum_top_el - [DQ LitAccumElList: lit_accum_el* dq_lit_term] :Dq -| [SQ SqConsDataList: sq_cons_data* sq_lit_term] :Sq + [DQ LitAccumElList: lit_accum_el<* dq_lit_term] :Dq +| [SQ SqConsDataList: sq_cons_data<* sq_lit_term] :Sq | [TILDE opt_tilde_data TILDE_NL] :Tilde -| [SQOPEN AccumElList: accum_el* SQCLOSE] :SubList +| [SQOPEN AccumElList: accum_el<* SQCLOSE] :SubList def accum_list [accum_top_el accum_list] :List @@ -808,20 +808,20 @@ def accumulate # def string_el - [E1 DQ LitStringElList: lit_string_el* dq_lit_term] :Dq -| [E1 SQ SqConsDataList: sq_cons_data* sq_lit_term] :Sq + [E1 DQ LitStringElList: lit_string_el<* dq_lit_term] :Dq +| [E1 SQ SqConsDataList: sq_cons_data<* sq_lit_term] :Sq | [E1 TILDE opt_tilde_data TILDE_NL] :Tilde | [E2 code_expr] :CodeExpr def lit_string_el [lit_dq_data] :ConsData -| [LIT_SQOPEN StringElList: string_el* LIT_SQCLOSE] :SubList +| [LIT_SQOPEN StringElList: string_el<* LIT_SQCLOSE] :SubList def string_top_el - [DQ LitStringElList: lit_string_el* dq_lit_term] :Dq -| [SQ SqConsDataList: sq_cons_data* sq_lit_term] :Sq + [DQ LitStringElList: lit_string_el<* dq_lit_term] :Dq +| [SQ SqConsDataList: sq_cons_data<* sq_lit_term] :Sq | [TILDE opt_tilde_data TILDE_NL] :Tilde -| [SQOPEN StringElList: string_el* SQCLOSE] :SubList +| [SQOPEN StringElList: string_el<* SQCLOSE] :SubList def string_list [string_top_el] :Base diff --git a/colm/compiler.cc b/colm/compiler.cc index 72cf99fa..f6276e9d 100644 --- a/colm/compiler.cc +++ b/colm/compiler.cc @@ -760,10 +760,11 @@ FsmGraph *Compiler::makeScanner() } LangEl *Compiler::makeRepeatProd( const InputLoc &loc, Namespace *nspace, - const String &repeatName, UniqueType *ut ) + const String &repeatName, UniqueType *ut, bool left ) { LangEl *prodName = addLangEl( this, nspace, repeatName, LangEl::NonTerm ); prodName->isRepeat = true; + prodName->leftRecursive = left; ProdElList *prodElList1 = new ProdElList; @@ -777,8 +778,14 @@ LangEl *Compiler::makeRepeatProd( const InputLoc &loc, Namespace *nspace, ProdEl *factor2 = new ProdEl( ProdEl::ReferenceType, InputLoc(), 0, false, typeRef2, 0 ); - prodElList1->append( factor1 ); - prodElList1->append( factor2 ); + if ( left ) { + prodElList1->append( factor2 ); + prodElList1->append( factor1 ); + } + else { + prodElList1->append( factor1 ); + prodElList1->append( factor2 ); + } Production *newDef1 = Production::cons( InputLoc(), prodName, prodElList1, String(), false, 0, @@ -815,8 +822,8 @@ LangEl *Compiler::makeListProd( const InputLoc &loc, Namespace *nspace, ProdEl *factor2 = new ProdEl( ProdEl::ReferenceType, loc, 0, false, typeRef2, 0 ); ProdElList *prodElList1 = new ProdElList; - prodElList1->append( factor1 ); prodElList1->append( factor2 ); + prodElList1->append( factor1 ); Production *newDef1 = Production::cons( loc, prodName, prodElList1, String(), false, 0, diff --git a/colm/compiler.h b/colm/compiler.h index 1b03504f..bf465dc6 100644 --- a/colm/compiler.h +++ b/colm/compiler.h @@ -281,6 +281,9 @@ struct LangEl : public DListEl<LangEl> bool parseStop; bool isEOF; + /* For a list or a repeat. Defaults to right recursive. */ + bool leftRecursive; + LangEl *repeatOf; /* Productions from the language element if it is a non-terminal. */ @@ -739,7 +742,7 @@ struct Compiler void printFirstSets(); LangEl *makeRepeatProd( const InputLoc &loc, Namespace *nspace, - const String &repeatName, UniqueType *ut ); + const String &repeatName, UniqueType *ut, bool left ); LangEl *makeListProd( const InputLoc &loc, Namespace *nspace, const String &listName, UniqueType *ut ); LangEl *makeOptProd( const InputLoc &loc, Namespace *nspace, diff --git a/colm/consinit.cc b/colm/consinit.cc index a2af94fd..4bd6e1c6 100644 --- a/colm/consinit.cc +++ b/colm/consinit.cc @@ -347,7 +347,7 @@ ProdEl *ConsInit::prodRefNameRepeat( const String &name ) { ProdEl *prodEl = prodElName( internal, name, NamespaceQual::cons( curNspace() ), 0, - RepeatRepeat, false ); + RepeatLeft, false ); return prodEl; } @@ -357,7 +357,7 @@ ProdEl *ConsInit::prodRefNameRepeat( const String &capture, const String &name ) ObjectField::RhsNameType, 0, capture ); ProdEl *prodEl = prodElName( internal, name, NamespaceQual::cons( curNspace() ), captureField, - RepeatRepeat, false ); + RepeatLeft, false ); return prodEl; } @@ -645,9 +645,12 @@ void ConsInit::optRepeat() ProdEl *prodEl1 = prodRefName( "Star", "STAR" ); Production *prod1 = production( prodEl1 ); - Production *prod2 = production(); + ProdEl *prodEl2 = prodRefName( "LeftStar", "LEFT_STAR" ); + Production *prod2 = production( prodEl2 ); + + Production *prod3 = production(); - definition( "opt_prod_repeat", prod1, prod2 ); + definition( "opt_prod_repeat", prod1, prod2, prod3 ); } void ConsInit::prodEl() @@ -848,6 +851,7 @@ void ConsInit::go( long activeRealm ) keyword( "STAR", "'*'"); keyword( "PLUS", "'+'"); + keyword( "LEFT_STAR", "'<*'"); keyword( "'['" ); keyword( "']'" ); keyword( "'|'" ); diff --git a/colm/exports.cc b/colm/exports.cc index 49228eff..2259c3c6 100644 --- a/colm/exports.cc +++ b/colm/exports.cc @@ -60,6 +60,7 @@ void Compiler::generateExports() "\n" "#include <colm/colm.h>\n" "#include <string>\n" + "#include <vector>\n" "\n"; out << @@ -112,11 +113,22 @@ void Compiler::generateExports() if ( mainReturnUT != 0 && mainReturnUT->langEl == lel ) { out << " " << lel->fullName << - "( colm_program *prg ) : __prg(prg), __tree(returnVal(prg)) {}\n"; + "( colm_program *prg ) : __prg(prg), __tree(returnVal(prg)) {\n"; + out << " }\n"; } out << " " << lel->fullName << - "( colm_program *prg, colm_tree *tree ) : __prg(prg), __tree(tree) {}\n"; + "( colm_program *prg, colm_tree *tree ) : __prg(prg), __tree(tree) {\n"; + + if ( lel->isRepeat && lel->leftRecursive ) { + out << + " while ( ! colm_repeat_end( __tree ) ) {\n" + " stack.push_back( colm_get_left_repeat_val( __tree ) );\n" + " __tree = colm_get_left_repeat_next( __tree );\n" + " }\n"; + } + + out << "}\n"; if ( lel->objectDef != 0 ) { FieldList &fieldList = lel->objectDef->fieldList; @@ -148,11 +160,19 @@ void Compiler::generateExports() "{ return (enum prod_name)__tree->prod_num; }\n"; } - if ( lel->isRepeat ) { - out << " " << "int end() { return colm_repeat_end( __tree ); }\n"; - out << " " << lel->refName << " next();\n"; - out << " " << lel->repeatOf->refName << " value();\n"; + if ( lel->leftRecursive ) { + out << " " << "std::vector<colm_tree*> stack;\n"; + out << " " << "int end() { return stack.size() == 0; }\n"; + out << " " << lel->refName << " next() { stack.pop_back(); return *this; }\n"; + out << " " << lel->repeatOf->refName << " value() { return " << + lel->repeatOf->refName << "( __prg, stack[stack.size()-1] ); }\n"; + } + else { + out << " " << "int end() { return colm_repeat_end( __tree ); }\n"; + out << " " << lel->refName << " next();\n"; + out << " " << lel->repeatOf->refName << " value();\n"; + } } if ( lel->isList ) { @@ -161,7 +181,6 @@ void Compiler::generateExports() out << " " << lel->repeatOf->refName << " value();\n"; } - out << "};"; closeNameSpace( out, lel->nspace ); out << "\n"; @@ -242,8 +261,8 @@ void Compiler::generateExportsImpl() } } - if ( lel->isRepeat ) { - out << lel->refName << " " << lel->declName << "::" << " next" + if ( lel->isRepeat && !lel->leftRecursive ) { + out << lel->refName << " " << lel->declName << "::" << "next" "() { return " << lel->refName << "( __prg, colm_get_repeat_next( __tree ) ); }\n"; @@ -253,7 +272,7 @@ void Compiler::generateExportsImpl() } if ( lel->isList ) { - out << lel->refName << " " << lel->declName << "::" << " next" + out << lel->refName << " " << lel->declName << "::" << "next" "() { return " << lel->refName << "( __prg, colm_get_repeat_next( __tree ) ); }\n"; diff --git a/colm/loadfinal.cc b/colm/loadfinal.cc index f05a99e1..54f2c6ab 100644 --- a/colm/loadfinal.cc +++ b/colm/loadfinal.cc @@ -849,6 +849,8 @@ struct LoadColm repeatType = RepeatOpt; break; case opt_repeat::LeftStar: + repeatType = RepeatLeft; + break; case opt_repeat::LeftPlus: error( OptRepeat.loc() ) << "<* and <+ are implemented as a " "colm transformation, they are not accepted at this stage" << endp; diff --git a/colm/loadinit.cc b/colm/loadinit.cc index fc75906c..ea5e7f00 100644 --- a/colm/loadinit.cc +++ b/colm/loadinit.cc @@ -62,6 +62,8 @@ void LoadInit::walkProdElList( String defName, ProdElList *list, prod_el_list &p RepeatType repeatType = RepeatNone; if ( El.OptRepeat().Star() != 0 ) repeatType = RepeatRepeat; + if ( El.OptRepeat().LeftStar() != 0 ) + repeatType = RepeatLeft; ProdEl *prodEl = prodElName( internal, typeName, NamespaceQual::cons( curNspace() ), diff --git a/colm/parsetree.h b/colm/parsetree.h index eea94454..6981880d 100644 --- a/colm/parsetree.h +++ b/colm/parsetree.h @@ -2110,7 +2110,8 @@ enum RepeatType { RepeatNone = 1, RepeatRepeat, RepeatList, - RepeatOpt + RepeatOpt, + RepeatLeft, }; /* diff --git a/colm/pdabuild.cc b/colm/pdabuild.cc index f61b45f9..64f7323d 100644 --- a/colm/pdabuild.cc +++ b/colm/pdabuild.cc @@ -99,6 +99,7 @@ LangEl::LangEl( Namespace *nspace, const String &name, Type type ) isRepeat(false), isList(false), isOpt(false), + leftRecursive(false), parseStop(false), isEOF(false), repeatOf(0), diff --git a/colm/prog.lm b/colm/prog.lm index e0ac8c22..635f0d92 100644 --- a/colm/prog.lm +++ b/colm/prog.lm @@ -37,16 +37,16 @@ void rewrite( P: ref<start> ) Additional = cons new_roots [Additional Def] } - else if match PE - [OptName: opt_prod_el_name Qual: region_qual Id: id "<*"] - { - parse LeftRepId: id "_lrep_[Id]" - PE = cons prod_el [OptName Qual LeftRepId] - - cons Def: cfl_def "def [LeftRepId] \[[LeftRepId] [Id]\] | \[\] - - Additional = cons new_roots [Additional Def] - } +# else if match PE +# [OptName: opt_prod_el_name Qual: region_qual Id: id "<*"] +# { +# parse LeftRepId: id "_lrep_[Id]" +# PE = cons prod_el [OptName Qual LeftRepId] +# +# cons Def: cfl_def "def [LeftRepId] \[[LeftRepId] [Id]\] | \[\] +# +# Additional = cons new_roots [Additional Def] +# } else if match PE [OptName: opt_prod_el_name Qual: region_qual Id: id "<+"] { @@ -61,7 +61,7 @@ void rewrite( P: ref<start> ) } while ( Additional.root_item ) { - P = cons start [Additional.root_item P.RootItemList] + P = cons start [P.RootItemList Additional.root_item] Additional = Additional._new_roots Modified = true } diff --git a/colm/resolve.cc b/colm/resolve.cc index 3202f197..a8c3df2a 100644 --- a/colm/resolve.cc +++ b/colm/resolve.cc @@ -361,11 +361,18 @@ void TypeRef::resolveRepeat( Compiler *pd ) LangEl *declLangEl = 0; switch ( repeatType ) { + case RepeatLeft: { + /* If the factor is a repeat, create the repeat element and link the + * factor to it. */ + String repeatName( 128, "_repeat_%s", typeName.data ); + declLangEl = pd->makeRepeatProd( loc, nspace, repeatName, uniqueType, true ); + break; + } case RepeatRepeat: { /* If the factor is a repeat, create the repeat element and link the * factor to it. */ String repeatName( 128, "_repeat_%s", typeName.data ); - declLangEl = pd->makeRepeatProd( loc, nspace, repeatName, uniqueType ); + declLangEl = pd->makeRepeatProd( loc, nspace, repeatName, uniqueType, false ); break; } case RepeatList: { diff --git a/colm/tree.c b/colm/tree.c index 4bd8db40..9e59c464 100644 --- a/colm/tree.c +++ b/colm/tree.c @@ -118,6 +118,30 @@ tree_t *colm_get_repeat_val( tree_t *tree ) return kid->tree; } +tree_t *colm_get_left_repeat_next( tree_t *tree ) +{ + kid_t *kid = tree->child; + + if ( tree->flags & AF_LEFT_IGNORE ) + kid = kid->next; + if ( tree->flags & AF_RIGHT_IGNORE ) + kid = kid->next; + + return kid->tree; +} + +tree_t *colm_get_left_repeat_val( tree_t *tree ) +{ + kid_t *kid = tree->child; + + if ( tree->flags & AF_LEFT_IGNORE ) + kid = kid->next; + if ( tree->flags & AF_RIGHT_IGNORE ) + kid = kid->next; + + return kid->next->tree; +} + int colm_repeat_end( tree_t *tree ) { kid_t *kid = tree->child; |