diff options
author | Adrian Thurston <thurston@complang.org> | 2011-11-07 06:46:53 +0000 |
---|---|---|
committer | Adrian Thurston <thurston@complang.org> | 2011-11-07 06:46:53 +0000 |
commit | 5f35eab59001a0f61fdd5e84b29283af4d451ea6 (patch) | |
tree | 179ebbf10613cb69b97738f260060926f2d8539c /colm | |
parent | 82314d73c5f964c1b60e15179fbb49db61b7c23d (diff) | |
download | colm-5f35eab59001a0f61fdd5e84b29283af4d451ea6.tar.gz |
Factored the reduction action into the bytecode loop. Next to fold the
recursive call into the parent loop to totally flatten. refs #332.
Diffstat (limited to 'colm')
-rw-r--r-- | colm/bytecode.c | 199 | ||||
-rw-r--r-- | colm/fsmrun.c | 81 | ||||
-rw-r--r-- | colm/parsedata.cc | 6 | ||||
-rw-r--r-- | colm/pdarun.h | 5 |
4 files changed, 221 insertions, 70 deletions
diff --git a/colm/bytecode.c b/colm/bytecode.c index 1bed6c59..1d3f0217 100644 --- a/colm/bytecode.c +++ b/colm/bytecode.c @@ -213,20 +213,44 @@ Word streamAppend( Program *prg, Tree **sp, Tree *input, Stream *stream ) } } -void parseStream( Program *prg, Tree **sp, Tree *input, Accum *accum, long stopId ) +enum ParseTokenResult parseStream( Program *prg, Tree **sp, Tree *input, Accum *accum, long stopId, enum ParseTokenEntry entry ) { + Stream *stream = (Stream*)input; + InputStream *inputStream = stream->in; + FsmRun *fsmRun = accum->fsmRun; + PdaRun *pdaRun = accum->pdaRun; + + if ( entry == PteReduction ) + goto ptrReduction; + if ( ! accum->pdaRun->parseError ) { accum->pdaRun->stopTarget = stopId; - Stream *stream = (Stream*)input; accum->fsmRun->curStream = input; - parseLoop( prg, sp, accum->pdaRun, accum->fsmRun, stream->in ); + + enum ParseTokenResult ptr = parseLoop( prg, sp, pdaRun, fsmRun, inputStream, PteToken ); + while ( ptr == PtrReduction ) { + return PtrReduction; + ptrReduction: + + ptr = parseLoop( prg, sp, pdaRun, fsmRun, inputStream, PteReduction ); + } } + + return PtrDone; } -Tree *parseFinish( Program *prg, Tree **sp, Accum *accum, int revertOn ) +enum ParseTokenResult parseFinish( Tree **result, Program *prg, Tree **sp, + Accum *accum, int revertOn, enum ParseTokenEntry entry ) { Stream *stream = (Stream*)extractInput( prg, accum ); + InputStream *inputStream = stream->in; + FsmRun *fsmRun = accum->fsmRun; + PdaRun *pdaRun = accum->pdaRun; + + if ( entry == PteReduction ) + goto pteReduction; + if ( accum->pdaRun->stopTarget > 0 ) { } @@ -237,7 +261,14 @@ Tree *parseFinish( Program *prg, Tree **sp, Accum *accum, int revertOn ) else { stream->in->eof = true; stream->in->later = false; - parseLoop( prg, sp, accum->pdaRun, accum->fsmRun, stream->in ); + enum ParseTokenResult ptr = parseLoop( prg, sp, pdaRun, fsmRun, inputStream, PteToken ); + + while ( ptr == PtrReduction ) { + return PteReduction; + pteReduction: + + ptr = parseLoop( prg, sp, pdaRun, fsmRun, inputStream, PteReduction ); + } } if ( !revertOn ) @@ -250,12 +281,46 @@ Tree *parseFinish( Program *prg, Tree **sp, Accum *accum, int revertOn ) if ( tree != 0 ) tree->flags |= AF_PARSED; - return tree; + *result = tree; + + return PtrDone; } -void undoParseStreamBc( Program *prg, Tree **sp, Stream *input, Accum *accum, long consumed ) +enum ParseTokenResult undoParseStream( Program *prg, Tree **sp, Stream *input, Accum *accum, + long consumed, enum ParseTokenEntry entry ) { - undoParseStream( prg, sp, input->in, accum->fsmRun, accum->pdaRun, consumed ); + InputStream *inputStream = input->in; + FsmRun *fsmRun = accum->fsmRun; + PdaRun *pdaRun = accum->pdaRun; + + if ( entry == PteReduction ) + goto pteReduction; + + if ( consumed < pdaRun->consumed ) { + /* Setup environment for going backwards until we reduced consumed to + * what we want. */ + pdaRun->numRetry += 1; + pdaRun->targetConsumed = consumed; + pdaRun->triggerUndo = 1; + + /* The parse loop will recognise the situation. */ + enum ParseTokenResult ptr = parseLoop( prg, sp, pdaRun, fsmRun, inputStream, PteToken ); + + while ( ptr == PtrReduction ) { + + return PteReduction; + pteReduction: + + ptr = parseLoop( prg, sp, pdaRun, fsmRun, inputStream, PteReduction ); + } + + /* Reset environment. */ + pdaRun->triggerUndo = 0; + pdaRun->targetConsumed = -1; + pdaRun->numRetry -= 1; + } + + return PtrDone; } Tree *streamPullBc( Program *prg, FsmRun *fsmRun, Stream *stream, Tree *length ) @@ -2088,7 +2153,24 @@ again: Tree *accum = vm_pop(); Tree *stream = vm_pop(); - parseStream( prg, sp, stream, (Accum*)accum, stopId ); + FsmRun *fsmRun = ((Accum*)accum)->fsmRun; + PdaRun *pdaRun = ((Accum*)accum)->pdaRun; + + enum ParseTokenResult ptr = parseStream( prg, sp, stream, (Accum*)accum, stopId, PteToken ); + + while ( ptr == PtrReduction ) { + Execution exec; + pdaRun->exec = &exec; + + /* Execution environment for the reduction code. */ + initReductionExecution( pdaRun->exec, prg, &pdaRun->rcodeCollect, + pdaRun, fsmRun, prg->rtd->prodInfo[pdaRun->reduction].frameId, + pdaRun->fi->codeWV, pdaRun->redLel->tree, 0, 0, fsmRun->mark ); + + reductionExecution( pdaRun->exec, sp ); + + ptr = parseStream( prg, sp, stream, (Accum*)accum, stopId, PteReduction ); + } treeDownref( prg, sp, stream ); treeDownref( prg, sp, accum ); @@ -2107,7 +2189,25 @@ again: Tree *stream = vm_pop(); long consumed = ((Accum*)accum)->pdaRun->consumed; - parseStream( prg, sp, stream, (Accum*)accum, stopId ); + + FsmRun *fsmRun = ((Accum*)accum)->fsmRun; + PdaRun *pdaRun = ((Accum*)accum)->pdaRun; + + enum ParseTokenResult ptr = parseStream( prg, sp, stream, (Accum*)accum, stopId, PteToken ); + + while ( ptr == PtrReduction ) { + Execution exec; + pdaRun->exec = &exec; + + /* Execution environment for the reduction code. */ + initReductionExecution( pdaRun->exec, prg, &pdaRun->rcodeCollect, + pdaRun, fsmRun, prg->rtd->prodInfo[pdaRun->reduction].frameId, + pdaRun->fi->codeWV, pdaRun->redLel->tree, 0, 0, fsmRun->mark ); + + reductionExecution( pdaRun->exec, sp ); + + ptr = parseStream( prg, sp, stream, (Accum*)accum, stopId, PteReduction ); + } //treeDownref( prg, sp, stream ); //treeDownref( prg, sp, accum ); @@ -2132,7 +2232,23 @@ again: debug( REALM_BYTECODE, "IN_PARSE_FRAG_BKT %ld", consumed ); - undoParseStreamBc( prg, sp, (Stream*)input, (Accum*)accum, consumed ); + FsmRun *fsmRun = ((Accum*)accum)->fsmRun; + PdaRun *pdaRun = ((Accum*)accum)->pdaRun; + + enum ParseTokenResult ptr = undoParseStream( prg, sp, (Stream*)input, (Accum*)accum, consumed, PteToken ); + while ( ptr == PtrReduction ) { + Execution exec; + pdaRun->exec = &exec; + + /* Execution environment for the reduction code. */ + initReductionExecution( pdaRun->exec, prg, &pdaRun->rcodeCollect, + pdaRun, fsmRun, prg->rtd->prodInfo[pdaRun->reduction].frameId, + pdaRun->fi->codeWV, pdaRun->redLel->tree, 0, 0, fsmRun->mark ); + + reductionExecution( pdaRun->exec, sp ); + + ptr = undoParseStream( prg, sp, (Stream*)input, (Accum*)accum, consumed, PteReduction ); + } treeDownref( prg, sp, accum ); treeDownref( prg, sp, input ); @@ -2143,7 +2259,26 @@ again: debug( REALM_BYTECODE, "IN_PARSE_FINISH_WC\n" ); Tree *accum = vm_pop(); - Tree *result = parseFinish( prg, sp, (Accum*)accum, false ); + Tree *result = 0; + + FsmRun *fsmRun = ((Accum*)accum)->fsmRun; + PdaRun *pdaRun = ((Accum*)accum)->pdaRun; + + enum ParseTokenResult ptr = parseFinish( &result, prg, sp, (Accum*)accum, false, PteToken ); + while ( ptr == PtrReduction ) { + Execution exec; + pdaRun->exec = &exec; + + /* Execution environment for the reduction code. */ + initReductionExecution( pdaRun->exec, prg, &pdaRun->rcodeCollect, + pdaRun, fsmRun, prg->rtd->prodInfo[pdaRun->reduction].frameId, + pdaRun->fi->codeWV, pdaRun->redLel->tree, 0, 0, fsmRun->mark ); + + reductionExecution( pdaRun->exec, sp ); + + ptr = parseFinish( &result, prg, sp, (Accum*)accum, false, PteReduction ); + } + vm_push( result ); treeDownref( prg, sp, accum ); if ( prg->induceExit ) @@ -2155,7 +2290,26 @@ again: Tree *accum = vm_pop(); long consumed = ((Accum*)accum)->pdaRun->consumed; - Tree *result = parseFinish( prg, sp, (Accum*)accum, true ); + Tree *result = 0; + + FsmRun *fsmRun = ((Accum*)accum)->fsmRun; + PdaRun *pdaRun = ((Accum*)accum)->pdaRun; + + enum ParseTokenResult ptr = parseFinish( &result, prg, sp, (Accum*)accum, true, PteToken ); + while ( ptr == PtrReduction ) { + Execution exec; + pdaRun->exec = &exec; + + /* Execution environment for the reduction code. */ + initReductionExecution( pdaRun->exec, prg, &pdaRun->rcodeCollect, + pdaRun, fsmRun, prg->rtd->prodInfo[pdaRun->reduction].frameId, + pdaRun->fi->codeWV, pdaRun->redLel->tree, 0, 0, fsmRun->mark ); + + reductionExecution( pdaRun->exec, sp ); + + ptr = parseFinish( &result, prg, sp, (Accum*)accum, true, PteReduction ); + } + vm_push( result ); treeUpref( result ); @@ -2179,7 +2333,24 @@ again: debug( REALM_BYTECODE, "IN_PARSE_FINISH_BKT\n" ); - undoParseStreamBc( prg, sp, ((Accum*)accum)->stream, (Accum*)accum, consumed ); + FsmRun *fsmRun = ((Accum*)accum)->fsmRun; + PdaRun *pdaRun = ((Accum*)accum)->pdaRun; + + enum ParseTokenResult ptr = undoParseStream( prg, sp, ((Accum*)accum)->stream, (Accum*)accum, consumed, PteToken ); + while ( ptr == PtrReduction ) { + Execution exec; + pdaRun->exec = &exec; + + /* Execution environment for the reduction code. */ + initReductionExecution( pdaRun->exec, prg, &pdaRun->rcodeCollect, + pdaRun, fsmRun, prg->rtd->prodInfo[pdaRun->reduction].frameId, + pdaRun->fi->codeWV, pdaRun->redLel->tree, 0, 0, fsmRun->mark ); + + reductionExecution( pdaRun->exec, sp ); + + ptr = undoParseStream( prg, sp, ((Accum*)accum)->stream, (Accum*)accum, consumed, PteReduction ); + } + ((Accum*)accum)->stream->in->eof = false; /* This needs an implementation. */ diff --git a/colm/fsmrun.c b/colm/fsmrun.c index 70e54c2b..3755bf3e 100644 --- a/colm/fsmrun.c +++ b/colm/fsmrun.c @@ -261,25 +261,6 @@ void streamPushTree( InputStream *inputStream, Tree *tree, int ignore ) inputStream->funcs->pushTree( inputStream, tree, ignore ); } -void undoParseStream( Program *prg, Tree **sp, InputStream *inputStream, FsmRun *fsmRun, PdaRun *pdaRun, long consumed ) -{ - if ( consumed < pdaRun->consumed ) { - /* Setup environment for going backwards until we reduced consumed to - * what we want. */ - pdaRun->numRetry += 1; - pdaRun->targetConsumed = consumed; - pdaRun->triggerUndo = 1; - - /* The parse loop will recognise the situation. */ - parseLoop( prg, sp, pdaRun, fsmRun, inputStream ); - - /* Reset environment. */ - pdaRun->triggerUndo = 0; - pdaRun->targetConsumed = -1; - pdaRun->numRetry -= 1; - } -} - void undoStreamPush( Program *prg, Tree **sp, InputStream *inputStream, long length ) { takeBackBuffered( inputStream ); @@ -764,36 +745,6 @@ void handleError( Program *prg, Tree **sp, PdaRun *pdaRun ) } } -void sendInput( Program *prg, Tree **sp, PdaRun *pdaRun, FsmRun *fsmRun, InputStream *inputStream, Kid *input ) -{ - if ( input != 0 ) { - /* Send the token to the parser. */ - attachIgnore( prg, sp, pdaRun, input ); - } - - assert( pdaRun->input == 0 ); - pdaRun->input = input; - - enum ParseTokenResult ptr = parseToken( prg, sp, pdaRun, fsmRun, - inputStream, input != 0 ? PteToken : PteError ); - - while ( ptr == PtrReduction ) { - Execution exec; - pdaRun->exec = &exec; - - /* Execution environment for the reduction code. */ - initReductionExecution( pdaRun->exec, prg, &pdaRun->rcodeCollect, - pdaRun, fsmRun, prg->rtd->prodInfo[pdaRun->reduction].frameId, - pdaRun->fi->codeWV, pdaRun->redLel->tree, 0, 0, fsmRun->mark ); - - reductionExecution( pdaRun->exec, sp ); - - ptr = parseToken( prg, sp, pdaRun, fsmRun, inputStream, PteReduction ); - } - - assert( ptr == PtrDone ); -} - void execGen( Program *prg, Tree **sp, InputStream *inputStream, FsmRun *fsmRun, PdaRun *pdaRun, long id ) { debug( REALM_PARSE, "token gen action: %s\n", @@ -1117,12 +1068,16 @@ void sendTreeIgnore( Program *prg, Tree **sp, PdaRun *pdaRun, FsmRun *fsmRun, In ignoreTree( prg, pdaRun, tree ); } -void parseLoop( Program *prg, Tree **sp, PdaRun *pdaRun, FsmRun *fsmRun, InputStream *inputStream ) +enum ParseTokenResult parseLoop( Program *prg, Tree **sp, PdaRun *pdaRun, + FsmRun *fsmRun, InputStream *inputStream, enum ParseTokenEntry entry ) { LangElInfo *lelInfo = prg->rtd->lelInfo; pdaRun->stop = false; + if ( entry == PteReduction ) + goto pteReduction; + while ( true ) { /* Pull the current scanner from the parser. This can change during * parsing due to inputStream pushes, usually for the purpose of includes. @@ -1203,7 +1158,29 @@ void parseLoop( Program *prg, Tree **sp, PdaRun *pdaRun, FsmRun *fsmRun, InputSt input = sendToken( prg, sp, inputStream, fsmRun, pdaRun, tokenId ); } - sendInput( prg, sp, pdaRun, fsmRun, inputStream, input ); + if ( input != 0 ) { + /* Send the token to the parser. */ + attachIgnore( prg, sp, pdaRun, input ); + } + + assert( pdaRun->input == 0 ); + pdaRun->input = input; + + enum ParseTokenResult ptr = parseToken( prg, sp, pdaRun, fsmRun, + inputStream, input != 0 ? PteToken : PteError ); + + + while ( ptr == PtrReduction ) { + + return PtrReduction; + pteReduction: + + ptr = parseToken( prg, sp, pdaRun, fsmRun, inputStream, PteReduction ); + } + + assert( ptr == PtrDone ); + + handleError( prg, sp, pdaRun ); skipSend: @@ -1242,4 +1219,6 @@ skipSend: break; } } + + return PtrDone; } diff --git a/colm/parsedata.cc b/colm/parsedata.cc index c06d5809..1753dc7c 100644 --- a/colm/parsedata.cc +++ b/colm/parsedata.cc @@ -1353,7 +1353,8 @@ void ParseData::parsePatterns() initPdaRun( repl->pdaRun, prg, pdaTables, fsmRun, repl->langEl->parserId, 0, false, 0 ); initFsmRun( fsmRun, prg ); newToken( prg, repl->pdaRun, fsmRun ); - parseLoop( prg, root, repl->pdaRun, fsmRun, in ); + ParseTokenResult result = parseLoop( prg, root, repl->pdaRun, fsmRun, in, PteToken ); + assert( result == PtrDone ); if ( repl->pdaRun->parseError ) cout << "parse error" << endp; free(in); @@ -1373,7 +1374,8 @@ void ParseData::parsePatterns() initPdaRun( pat->pdaRun, prg, pdaTables, fsmRun, pat->langEl->parserId, 0, false, 0 ); initFsmRun( fsmRun, prg ); newToken( prg, pat->pdaRun, fsmRun ); - parseLoop( prg, root, pat->pdaRun, fsmRun, in ); + ParseTokenResult result = parseLoop( prg, root, pat->pdaRun, fsmRun, in, PteToken ); + assert( result == PtrDone ); if ( pat->pdaRun->parseError ) cout << "parse error" << endp; free( in ); diff --git a/colm/pdarun.h b/colm/pdarun.h index e171d1ee..f80411df 100644 --- a/colm/pdarun.h +++ b/colm/pdarun.h @@ -358,12 +358,11 @@ void newToken( struct ColmProgram *prg, PdaRun *pdaRun, FsmRun *fsmRun ); void breakRunBuf( FsmRun *fsmRun ); void fsmExecute( FsmRun *fsmRun, InputStream *inputStream ); Kid *sendNamedLangEl( struct ColmProgram *prg, Tree **sp, PdaRun *pdaRun, FsmRun *fsmRun, InputStream *inputStream ); -void parseLoop( struct ColmProgram *prg, Tree **sp, PdaRun *pdaRun, FsmRun *fsmRun, InputStream *inputStream ); +enum ParseTokenResult parseLoop( struct ColmProgram *prg, Tree **sp, + PdaRun *pdaRun, FsmRun *fsmRun, InputStream *inputStream, enum ParseTokenEntry entry ); void initBindings( PdaRun *pdaRun ); Tree *getParsedRoot( PdaRun *pdaRun, int stop ); void pushBtPoint( struct ColmProgram *prg, PdaRun *pdaRun, Tree *tree ); -void undoParseStream( struct ColmProgram *prg, Tree **sp, InputStream *inputStream, FsmRun *fsmRun, - PdaRun *pdaRun, long consumed ); #ifdef __cplusplus } |