summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2009-02-22 22:33:01 +0000
committerAdrian Thurston <thurston@complang.org>2009-02-22 22:33:01 +0000
commit48df5c80840ff189c0e019376c74630284eb6f3c (patch)
tree72989c9f2995d37ea849087c73350f040400d2dd
parent76ab0efa0b78d21fa8f2f2398a2d232386640bd0 (diff)
downloadcolm-48df5c80840ff189c0e019376c74630284eb6f3c.tar.gz
Can now set the precedence of a production as you can in bison.
-rw-r--r--colm/lmparse.kh2
-rw-r--r--colm/lmparse.kl60
-rw-r--r--colm/parsedata.cpp17
-rw-r--r--colm/pdabuild.cpp4
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 );