summaryrefslogtreecommitdiff
path: root/colm
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2011-11-07 06:46:53 +0000
committerAdrian Thurston <thurston@complang.org>2011-11-07 06:46:53 +0000
commit5f35eab59001a0f61fdd5e84b29283af4d451ea6 (patch)
tree179ebbf10613cb69b97738f260060926f2d8539c /colm
parent82314d73c5f964c1b60e15179fbb49db61b7c23d (diff)
downloadcolm-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.c199
-rw-r--r--colm/fsmrun.c81
-rw-r--r--colm/parsedata.cc6
-rw-r--r--colm/pdarun.h5
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
}