From 48df5c80840ff189c0e019376c74630284eb6f3c Mon Sep 17 00:00:00 2001 From: Adrian Thurston Date: Sun, 22 Feb 2009 22:33:01 +0000 Subject: Can now set the precedence of a production as you can in bison. --- colm/lmparse.kh | 2 +- colm/lmparse.kl | 60 ++++++++++++++++++++++++++++++++++++++++-------------- colm/parsedata.cpp | 17 +++++++++------- colm/pdabuild.cpp | 4 ++-- 4 files changed, 58 insertions(+), 25 deletions(-) diff --git a/colm/lmparse.kh b/colm/lmparse.kh index 47678353..0184a76d 100644 --- a/colm/lmparse.kh +++ b/colm/lmparse.kh @@ -79,7 +79,7 @@ struct Parser void addRegularDef( const InputLoc &loc, Namespace *nspace, const String &name, JoinOrLm *joinOrLm, bool isInstance ); void addProduction( InputLoc &loc, const String &name, - ProdElList *prodElList, bool commit, CodeBlock *redBlock ); + ProdElList *prodElList, bool commit, CodeBlock *redBlock, KlangEl *predOf ); /* Report an error encountered by the parser. */ ostream &parse_error( int tokId, Token &token ); diff --git a/colm/lmparse.kl b/colm/lmparse.kl index 489f0bf8..510a9127 100644 --- a/colm/lmparse.kl +++ b/colm/lmparse.kl @@ -189,7 +189,7 @@ generic_def: KW_Map TK_Word '[' type_ref type_ref ']' /* Add one empty production. */ ProdElList *emptyList = new ProdElList; - addProduction( $1->loc, $2->data, emptyList, false, 0 ); + addProduction( $1->loc, $2->data, emptyList, false, 0, 0 ); nspace->genericList.append( generic ); langEl->generic = generic; @@ -213,7 +213,7 @@ generic_def: KW_List TK_Word '[' type_ref ']' /* Add one empty production. */ ProdElList *emptyList = new ProdElList; - addProduction( $1->loc, $2->data, emptyList, false, 0 ); + addProduction( $1->loc, $2->data, emptyList, false, 0, 0 ); nspace->genericList.append( generic ); langEl->generic = generic; @@ -255,28 +255,38 @@ pred_type: KW_Left final { predType = PredLeft; }; pred_type: KW_Right final { predType = PredRight; }; pred_type: KW_Nonassoc final { predType = PredNonassoc; }; -pred_token_list: pred_token_list ',' pred_token; -pred_token_list: pred_token; +pred_token_list: pred_token_list ',' pred_token + final { + $3->factor->langEl->predType = predType; + $3->factor->langEl->predValue = pd->predValue; + }; + +pred_token_list: pred_token + final { + $1->factor->langEl->predType = predType; + $1->factor->langEl->predValue = pd->predValue; + }; + +nonterm pred_token +{ + PdaFactor *factor; +}; pred_token: region_qual TK_Word final { - PdaFactor *factor = new PdaFactor( $2->loc, false, $1->nspaceQual, + $$->factor = new PdaFactor( $2->loc, false, $1->nspaceQual, $2->data, 0, false, false ); - pd->resolveReferenceFactor( factor ); - factor->langEl->predType = predType; - factor->langEl->predValue = pd->predValue; + pd->resolveReferenceFactor( $$->factor ); }; pred_token: region_qual TK_Literal final { PdaLiteral *literal = new PdaLiteral( $2->loc, *$2 ); - PdaFactor *factor = new PdaFactor( $2->loc, false, $1->nspaceQual, + $$->factor = new PdaFactor( $2->loc, false, $1->nspaceQual, literal, 0, false, false ); - pd->resolveLiteralFactor( factor ); - factor->langEl->predType = predType; - factor->langEl->predValue = pd->predValue; + pd->resolveLiteralFactor( $$->factor ); }; cfl_def: cfl_def_head obj_var_list properties_list cfl_prod_list @@ -321,9 +331,27 @@ property: prodName->reduceFirst = true; }; -define_prod: '[' prod_el_list ']' opt_commit opt_reduce_code +nonterm opt_prec +{ + KlangEl *predOf; +}; + +opt_prec: + final { + $$->predOf = 0; + }; + +opt_prec: + KW_Prec pred_token final { - addProduction( $1->loc, curDefineId, curProdElList, $4->commit, $5->codeBlock ); + $$->predOf = $2->factor->langEl; + }; + + +define_prod: '[' prod_el_list ']' opt_commit opt_reduce_code opt_prec + final { + addProduction( $1->loc, curDefineId, curProdElList, $4->commit, + $5->codeBlock, $6->predOf ); }; obj_var_list: obj_var_list var_def @@ -1990,7 +2018,7 @@ void Parser::addRegularDef( const InputLoc &loc, Namespace *nspace, } void Parser::addProduction( InputLoc &loc, const String &name, - ProdElList *prodElList, bool commit, CodeBlock *redBlock ) + ProdElList *prodElList, bool commit, CodeBlock *redBlock, KlangEl *predOf ) { /* Get the language element. */ KlangEl *prodName = getKlangEl( pd, namespaceStack.top(), name ); @@ -2012,6 +2040,8 @@ void Parser::addProduction( InputLoc &loc, const String &name, * region just created. We need it in the parent. */ nspace->parentNamespace->symbolMap.insert( name, prodName ); } + + newDef->predOf = predOf; } ostream &Parser::parse_error( int tokId, Token &token ) diff --git a/colm/parsedata.cpp b/colm/parsedata.cpp index 116e576d..5bcb1282 100644 --- a/colm/parsedata.cpp +++ b/colm/parsedata.cpp @@ -1252,13 +1252,16 @@ void ParseData::resolveProductionEls() for ( ProdElList::Iter fact = *prod->prodElList; fact.lte(); fact++ ) resolveFactor( fact ); - /* Compute the precedence of the productions. */ - for ( ProdElList::Iter fact = prod->prodElList->last(); fact.gtb(); fact-- ) { - /* Production inherits the precedence of the last terminal with - * precedence. */ - if ( fact->langEl->predType != PredNone ) { - prod->predOf = fact->langEl; - break; + /* If there is no explicit precdence ... */ + if ( prod->predOf == 0 ) { + /* Compute the precedence of the productions. */ + for ( ProdElList::Iter fact = prod->prodElList->last(); fact.gtb(); fact-- ) { + /* Production inherits the precedence of the last terminal with + * precedence. */ + if ( fact->langEl->predType != PredNone ) { + prod->predOf = fact->langEl; + break; + } } } } diff --git a/colm/pdabuild.cpp b/colm/pdabuild.cpp index 37fe8304..308a57ab 100644 --- a/colm/pdabuild.cpp +++ b/colm/pdabuild.cpp @@ -954,12 +954,12 @@ again: for ( int i = 0; i < trans->actions.length(); i++ ) { KlangEl *li = predOf( trans, trans->actions[i] ); - if ( li != 0 && li->predValue != PredNone ) { + if ( li != 0 && li->predType != PredNone ) { /* Find another action with precedence. */ for ( int j = i+1; j < trans->actions.length(); j++ ) { KlangEl *lj = predOf( trans, trans->actions[j] ); - if ( lj != 0 && lj->predValue != PredNone ) { + if ( lj != 0 && lj->predType != PredNone ) { /* Conflict to check. */ bool swap = precedenceSwap( trans->actions[i], trans->actions[j], li, lj ); -- cgit v1.2.1