diff options
author | Adrian Thurston <thurston@complang.org> | 2008-11-10 23:22:13 +0000 |
---|---|---|
committer | Adrian Thurston <thurston@complang.org> | 2008-11-10 23:22:13 +0000 |
commit | eca13f865eb3d00191f1e88d0d83e5a8ef70c5b8 (patch) | |
tree | 433ce7949f4e209ba36a7343a67bf025d2d13892 | |
parent | 1c9e0e428092035b88770b5ee013b7f8e6d180c5 (diff) | |
download | colm-eca13f865eb3d00191f1e88d0d83e5a8ef70c5b8.tar.gz |
Need to consider causeReduce when backing up over rcode in the the commit function.
-rw-r--r-- | colm/pdarun.cpp | 67 |
1 files changed, 56 insertions, 11 deletions
diff --git a/colm/pdarun.cpp b/colm/pdarun.cpp index 25a088f8..8f2193d4 100644 --- a/colm/pdarun.cpp +++ b/colm/pdarun.cpp @@ -138,14 +138,24 @@ bool been_committed( Kid *kid ) return kid->tree->alg->flags & AF_COMMITTED; } +Code *backup_over_rcode( Code *rcode ) +{ + Word len; + rcode -= 4; + read_word_p( len, rcode ); + rcode -= len; + return rcode; +} + /* The top level of the stack is linked right-to-left. Trees underneath are * linked left-to-right. */ -void commit_kid( PdaRun *parser, Tree **root, Kid *lel, Code *&prcode ) +void commit_kid( PdaRun *parser, Tree **root, Kid *lel, Code *&rcode ) { Alg *alg = 0; Tree *tree = 0; Tree **sp = root; Tree *restore = 0; + long causeReduce = 0; head: /* Commit */ @@ -160,21 +170,50 @@ head: if ( alg->parsed != 0 ) tree = alg->parsed; + /* Check for reverse code. */ restore = 0; if ( alg->flags & AF_HAS_RCODE ) { - prcode -= 4; - Word len; - read_word_p( len, prcode ); - prcode -= len; - - if ( *prcode == IN_RESTORE_LHS ) { - cout << "has restore_lhs" << endl; - read_tree_p( restore, (prcode+1) ); + /* If tree caused some reductions, now is not the right time to backup + * over the reverse code. We need to backup over the reductions first. Store + * the count of the reductions and do it when the count drops to zero. */ + if ( alg->causeReduce > 0 ) { + /* The top reduce block does not correspond to this alg. */ + #ifdef COLM_LOG_PARSE + cerr << "commit: causeReduce found, delaying backup: " << (long)alg->causeReduce << endl; + #endif + causeReduce = alg->causeReduce; } + else { + rcode = backup_over_rcode( rcode ); + if ( *rcode == IN_RESTORE_LHS ) { + #if COLM_LOG_PARSE + cerr << "commit: has restore_lhs" << endl; + #endif + read_tree_p( restore, (rcode+1) ); + } + } } + + /* Assert that we have the right restore tree. */ assert( alg->parsed == restore ); + /* Check causeReduce, might be time to backup over the reverse code + * belonging to a nonterminal that caused previous reductions. */ + if ( tree->id >= parser->tables->rtd->firstNonTermId && + !(alg->flags & AF_GENERATED) && causeReduce > 0 ) + { + causeReduce -= 1; + + if ( causeReduce == 0 ) { + #ifdef COLM_LOG_PARSE + cerr << "commit: causeReduce dropped to zero, backing up over rcode" << endl; + #endif + + /* Cause reduce just dropped down to zero. */ + rcode = backup_over_rcode( rcode ); + } + } /* Reset retries. */ if ( alg->retry_lower > 0 ) { @@ -231,10 +270,12 @@ void commit_full( PdaRun *parser ) Tree **sp = parser->root; Kid *kid = parser->stackTop; - Code *prcode = parser->allReverseCode->data + parser->allReverseCode->length(); + Code *rcode = parser->allReverseCode->data + parser->allReverseCode->length(); + /* The top level of the stack is linked right to left. This is the + * traversal order we need for committing. */ while ( kid != 0 && !been_committed( kid ) ) { - commit_kid( parser, sp, kid, prcode ); + commit_kid( parser, sp, kid, rcode ); kid = kid->next; } @@ -506,6 +547,10 @@ again: /* If the lhs changed then store the original, otherwise downref * since we took a copy above. */ if ( parsed != redLel->tree ) { + #ifdef COLM_LOG_PARSE + cerr << "lhs tree was modified, adding a restore instruction" << endl; + #endif + redAlg->parsed = parsed; reverseCode.append( IN_RESTORE_LHS ); reverseCode.appendWord( (Word)parsed ); |