summaryrefslogtreecommitdiff
path: root/src/pdabuild.cc
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@colm.net>2019-09-08 21:11:17 -0600
committerAdrian Thurston <thurston@colm.net>2019-09-08 21:11:17 -0600
commitc860c61607117582abd8f23881eed87957197484 (patch)
tree4d4e65dddc710e15f008189a9308d95924350c3f /src/pdabuild.cc
parentf37c916aed2600951b8966a86020406b0b0542cf (diff)
downloadcolm-c860c61607117582abd8f23881eed87957197484.tar.gz
moved the original colm src dir to /colm
Diffstat (limited to 'src/pdabuild.cc')
-rw-r--r--src/pdabuild.cc2204
1 files changed, 0 insertions, 2204 deletions
diff --git a/src/pdabuild.cc b/src/pdabuild.cc
deleted file mode 100644
index ba4850df..00000000
--- a/src/pdabuild.cc
+++ /dev/null
@@ -1,2204 +0,0 @@
-/*
- * Copyright 2006-2018 Adrian Thurston <thurston@colm.net>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define EOF_REGION 0
-
-#include <stdio.h>
-#include <string.h>
-#include <stdbool.h>
-#include <assert.h>
-
-#include <iostream>
-
-/* Dumping the fsm. */
-#include <mergesort.h>
-
-/* Parsing. */
-#include "compiler.h"
-#include "pdacodegen.h"
-
-using std::endl;
-using std::cerr;
-using std::cout;
-
-char startDefName[] = "start";
-
-extern "C" tree_t **internal_host_call( program_t *prg, long code, tree_t **sp )
-{
- return 0;
-}
-
-extern "C" void internal_commit_reduce_forward( program_t *prg, tree_t **root,
- struct pda_run *pda_run, parse_tree_t *pt )
-{
- commit_clear_parse_tree( prg, root, pda_run, pt->child );
-}
-
-extern "C" long internal_commit_union_sz( int reducer )
-{
- return 0;
-}
-
-extern "C" void internal_init_need()
-{
-}
-
-extern "C" int internal_reducer_need_tok( program_t *prg, struct pda_run *, int id )
-{
- return 3;
-}
-
-extern "C" int internal_reducer_need_ign( program_t *prg, struct pda_run * )
-{
- return 3;
-}
-
-/* Count the transitions in the fsm by walking the state list. */
-int countTransitions( PdaGraph *fsm )
-{
- int numTrans = 0;
- PdaState *state = fsm->stateList.head;
- while ( state != 0 ) {
- numTrans += state->transMap.length();
- state = state->next;
- }
- return numTrans;
-}
-
-LangEl::LangEl( Namespace *nspace, const String &name, Type type )
-:
- nspace(nspace),
- name(name),
- lit(name),
- type(type),
- id(-1),
- numAppearances(0),
- commit(false),
- isIgnore(false),
- reduceFirst(false),
- isLiteral(false),
- isRepeat(false),
- isList(false),
- isOpt(false),
- parseStop(false),
- isEOF(false),
- repeatOf(0),
- tokenDef(0),
- rootDef(0),
- termDup(0),
- eofLel(0),
- pdaGraph(0),
- pdaTables(0),
- transBlock(0),
- objectDef(0),
- thisSize(0),
- ofiOffset(0),
- parserId(-1),
- predType(PredNone),
- predValue(0),
- contextDef(0),
- contextIn(0),
- noPreIgnore(false),
- noPostIgnore(false),
- isZero(false)
-{
-}
-
-PdaGraph *ProdElList::walk( Compiler *pd, Production *prod )
-{
- PdaGraph *prodFsm = new PdaGraph();
- PdaState *last = prodFsm->addState();
- prodFsm->setStartState( last );
-
- int prodLength = 0;
- for ( Iter prodEl = first(); prodEl.lte(); prodEl++, prodLength++ ) {
- //PdaGraph *itemFsm = prodEl->walk( pd );
- long value = prodEl->langEl->id;
-
- PdaState *newState = prodFsm->addState();
- PdaTrans *newTrans = prodFsm->appendNewTrans( last, newState, value, value );
-
- newTrans->isShift = true;
- newTrans->shiftPrior = prodEl->priorVal;
- //cerr << "PRIOR VAL: " << newTrans->shiftPrior << endl;
-
- if ( prodEl->commit ) {
- //cout << "COMMIT: inserting commit of length: " << pd->prodLength << endl;
- /* Insert the commit into transitions out of last */
- for ( TransMap::Iter trans = last->transMap; trans.lte(); trans++ )
- trans->value->commits.insert( prodLength );
- }
-
- last = newState;
- }
-
- /* Make the last state the final state. */
- prodFsm->setFinState( last );
- return prodFsm;
-}
-
-
-ProdElList *Compiler::makeProdElList( LangEl *langEl )
-{
- ProdElList *prodElList = new ProdElList();
- UniqueType *uniqueType = findUniqueType( TYPE_TREE, langEl );
- TypeRef *typeRef = TypeRef::cons( internal, uniqueType );
- prodElList->append( new ProdEl( internal, typeRef ) );
- prodElList->tail->langEl = langEl;
- return prodElList;
-}
-
-void Compiler::makeDefinitionNames()
-{
- for ( LelList::Iter lel = langEls; lel.lte(); lel++ ) {
- int prodNum = 1;
- for ( LelDefList::Iter def = lel->defList; def.lte(); def++ ) {
- def->data.setAs( lel->name.length() + 32, "%s-%i",
- lel->name.data, prodNum++ );
- }
- }
-}
-
-/* Make sure there there are no language elements whose type is unkonwn. This
- * can happen when an id is used on the rhs of a definition but is not defined
- * as anything. */
-void Compiler::noUndefindLangEls()
-{
- for ( LelList::Iter lel = langEls; lel.lte(); lel++ ) {
- if ( lel->type == LangEl::Unknown )
- error() << "'" << lel->name << "' was not defined as anything" << endp;
- }
-}
-
-void Compiler::makeLangElIds()
-{
- /* The first id 0 is reserved for the stack sentinal. A negative id means
- * error to the parsing function, inducing backtracking. */
- nextLelId = 1;
-
- /* First pass assigns to the user terminals. */
- for ( LelList::Iter lel = langEls; lel.lte(); lel++ ) {
- /* Must be a term, and not any of the special reserved terminals.
- * Remember if the non terminal is a user non terminal. */
- if ( lel->type == LangEl::Term &&
- !lel->isEOF &&
- lel != errorLangEl &&
- lel != noTokenLangEl )
- {
- lel->id = nextLelId++;
- }
- }
-
- //eofLangEl->id = nextLelId++;
- for ( LelList::Iter lel = langEls; lel.lte(); lel++ ) {
- /* Must be a term, and not any of the special reserved terminals.
- * Remember if the non terminal is a user non terminal. */
- if ( lel->isEOF )
- lel->id = nextLelId++;
- }
-
- /* Next assign to the eof notoken, which we always create. */
- noTokenLangEl->id = nextLelId++;
-
- /* Possibly assign to the error language element. */
- if ( errorLangEl != 0 )
- errorLangEl->id = nextLelId++;
-
- /* Save this for the code generation. */
- firstNonTermId = nextLelId;
-
- /* A third and final pass assigns to everything else. */
- for ( LelList::Iter lel = langEls; lel.lte(); lel++ ) {
- /* Anything else not yet assigned gets assigned now. */
- if ( lel->id < 0 )
- lel->id = nextLelId++;
- }
-
- assert( ptrLangEl->id == LEL_ID_PTR );
- assert( strLangEl->id == LEL_ID_STR );
- assert( ignoreLangEl->id == LEL_ID_IGNORE );
-}
-
-void Compiler::makeStructElIds()
-{
- firstStructElId = nextLelId;
-
- /* Start at the next lang el id and go up from there. Using disjoint sets
- * allows us to verify that a tree is a tree and struct is a struct because
- * the ID field is at the same offset. */
- int nextId = nextLelId;
- for ( StructElList::Iter sel = structEls; sel.lte(); sel++ )
- sel->id = nextId++;
-
- structInbuiltId = nextId++;
- structInputId = nextId++;
- structStreamId = nextId++;
-}
-
-void Compiler::refNameSpace( LangEl *lel, Namespace *nspace )
-{
- if ( nspace == rootNamespace ) {
- lel->refName = "::" + lel->refName;
- return;
- }
-
- lel->refName = nspace->name + "::" + lel->refName;
- lel->declName = nspace->name + "::" + lel->declName;
- lel->xmlTag = nspace->name + "::" + lel->xmlTag;
- refNameSpace( lel, nspace->parentNamespace );
-}
-
-void Compiler::makeLangElNames()
-{
- for ( LelList::Iter lel = langEls; lel.lte(); lel++ ) {
- lel->fullName = lel->name;
- lel->fullLit = lel->lit;
- lel->refName = lel->lit;
- lel->declName = lel->lit;
- lel->xmlTag = lel->name;
-
- /* If there is also a namespace next to the type, we add a prefix to
- * the type. It's not convenient to name C++ classes the same as a
- * namespace in the same scope. We don't want to restrict colm, so we
- * add a workaround for the least-common case. The type gets t_ prefix.
- * */
- Namespace *nspace = lel->nspace->findNamespace( lel->name );
- if ( nspace != 0 ) {
- lel->refName = "t_" + lel->refName;
- lel->fullName = "t_" + lel->fullName;
- lel->declName = "t_" + lel->declName;
- lel->xmlTag = "t_" + lel->xmlTag;
- }
-
- refNameSpace( lel, lel->nspace );
- }
-}
-
-/* Set up dot sets, shift info, and prod sets. */
-void Compiler::makeProdFsms()
-{
- /* There are two items in the index for each production (high and low). */
- int indexLen = prodList.length() * 2;
- dotItemIndex.setAsNew( indexLen );
- int dsiLow = 0, indexPos = 0;
-
- /* Build FSMs for all production language elements. */
- for ( DefList::Iter prod = prodList; prod.lte(); prod++ )
- prod->fsm = prod->prodElList->walk( this, prod );
-
- makeNonTermFirstSets();
- makeFirstSets();
-
- /* Build FSMs for all production language elements. */
- for ( DefList::Iter prod = prodList; prod.lte(); prod++ ) {
- if ( addUniqueEmptyProductions ) {
- /* This must be re-implemented. */
- assert( false );
- //if ( !prod->isLeftRec && prod->uniqueEmptyLeader != 0 ) {
- // PdaGraph *emptyLeader = prod->uniqueEmptyLeader->walk( this );
- // emptyLeader->concatOp( prod->fsm );
- // prod->fsm = emptyLeader;
- //}
- }
-
- /* Compute the machine's length. */
- prod->fsmLength = prod->fsm->fsmLength( );
-
- /* Productions have a unique production id for each final state.
- * This lets us use a production length specific to each final state.
- * Start states are always isolated therefore if the start state is
- * final then reductions from it will always have a fixed production
- * length. This is a simple method for determining the length
- * of zero-length derivations when reducing. */
-
- /* Number of dot items needed for the production is elements + 1
- * because the dot can be before the first and after the last element. */
- int numForProd = prod->fsm->stateList.length() + 1;
-
- /* Set up the low and high values in the index for this production. */
- dotItemIndex.data[indexPos].key = dsiLow;
- dotItemIndex.data[indexPos].value = prod;
- dotItemIndex.data[indexPos+1].key = dsiLow + numForProd - 1;
- dotItemIndex.data[indexPos+1].value = prod;
-
- int dsi = dsiLow;
- for ( PdaStateList::Iter state = prod->fsm->stateList; state.lte(); state++, dsi++ ) {
- /* All transitions are shifts. */
- for ( TransMap::Iter out = state->transMap; out.lte(); out++ )
- assert( out->value->isShift );
-
- state->dotSet.insert( dsi );
- }
-
- /* Move over the production. */
- dsiLow += numForProd;
- indexPos += 2;
-
- if ( prod->prodCommit ) {
- for ( PdaStateSet::Iter fin = prod->fsm->finStateSet; fin.lte(); fin++ ) {
- int length = prod->fsmLength;
- //cerr << "PENDING COMMIT IN FINAL STATE of " << prod->prodId <<
- // " with len: " << length << endl;
- (*fin)->pendingCommits.insert( ProdIdPair( prod->prodId, length ) );
- }
- }
- }
-
- /* Make the final state specific prod id to prod id mapping. */
- prodIdIndex = new Production*[prodList.length()];
- for ( DefList::Iter prod = prodList; prod.lte(); prod++ )
- prodIdIndex[prod->prodId] = prod;
-}
-
-/* Want the first set of over src. If the first set contains epsilon, go over
- * it and over tab. If overSrc is the end of the production, find the follow
- * from the table, taking only the characters on which the parent is reduced.
- * */
-void Compiler::findFollow( AlphSet &result, PdaState *overTab,
- PdaState *overSrc, Production *parentDef )
-{
- if ( overSrc->isFinState() ) {
- assert( overSrc->transMap.length() == 0 );
-
- /* At the end of the production. Turn to the table. */
- long redCode = makeReduceCode( parentDef->prodId, false );
- for ( TransMap::Iter tabTrans = overTab->transMap; tabTrans.lte(); tabTrans++ ) {
- for ( ActDataList::Iter adl = tabTrans->value->actions; adl.lte(); adl++ ) {
- if ( *adl == redCode )
- result.insert( tabTrans->key );
- }
- }
- }
- else {
- /* Get the first set of the item. If the first set contains epsilon
- * then move over overSrc and overTab and recurse. */
- assert( overSrc->transMap.length() == 1 );
- TransMap::Iter pastTrans = overSrc->transMap;
-
- LangEl *langEl = langElIndex[pastTrans->key];
- if ( langEl != 0 && langEl->type == LangEl::NonTerm ) {
- bool hasEpsilon = false;
- for ( LelDefList::Iter def = langEl->defList; def.lte(); def++ ) {
- result.insert( def->firstSet );
-
- if ( def->firstSet.find( -1 ) )
- hasEpsilon = true;
- }
-
- /* Find the equivalent state in the parser. */
- if ( hasEpsilon ) {
- PdaTrans *tabTrans = overTab->findTrans( pastTrans->key );
- findFollow( result, tabTrans->toState,
- pastTrans->value->toState, parentDef );
- }
-
- /* Now possibly the dup. */
- if ( langEl->termDup != 0 )
- result.insert( langEl->termDup->id );
- }
- else {
- result.insert( pastTrans->key );
- }
- }
-}
-
-PdaState *Compiler::followProd( PdaState *tabState, PdaState *prodState )
-{
- while ( prodState->transMap.length() == 1 ) {
- TransMap::Iter prodTrans = prodState->transMap;
- PdaTrans *tabTrans = tabState->findTrans( prodTrans->key );
- prodState = prodTrans->value->toState;
- tabState = tabTrans->toState;
- }
- return tabState;
-}
-
-void Compiler::trySetTime( PdaTrans *trans, long code, long &time )
-{
- /* Find the item. */
- for ( ActDataList::Iter adl = trans->actions; adl.lte(); adl++ ) {
- if ( *adl == code ) {
- /* If the time of the shift is not already set, set it. */
- if ( trans->actOrds[adl.pos()] == 0 ) {
- //cerr << "setting time: state = " << tabState->stateNum
- // << ", trans = " << tabTrans->lowKey
- // << ", time = " << time << endl;
- trans->actOrds[adl.pos()] = time++;
- }
- break;
- }
- }
-}
-
-/* Go down a defintiion and then handle the follow actions. */
-void Compiler::pdaOrderFollow( LangEl *rootEl, PdaState *tabState,
- PdaTrans *tabTrans, PdaTrans *srcTrans, Production *parentDef,
- Production *definition, long &time )
-{
- /* We need the follow from tabState/srcState over the defintion we are
- * currently processing. */
- PdaState *overTab = tabTrans->toState;
- PdaState *overSrc = srcTrans->toState;
-
- AlphSet alphSet;
- if ( parentDef == rootEl->rootDef )
- alphSet.insert( rootEl->eofLel->id );
- else
- findFollow( alphSet, overTab, overSrc, parentDef );
-
- /* Now follow the production to find out where it expands to. */
- PdaState *expandToState = followProd( tabState, definition->fsm->startState );
-
- /* Find the reduce item. */
- long redCode = makeReduceCode( definition->prodId, false );
-
- for ( TransMap::Iter tt = expandToState->transMap; tt.lte(); tt++ ) {
- if ( alphSet.find( tt->key ) ) {
- trySetTime( tt->value, redCode, time );
-
- /* If the items token region is not recorded in the state, do it now. */
- addRegion( expandToState, tt->value, tt->key,
- tt->value->noPreIgnore, tt->value->noPostIgnore );
- }
- }
-}
-
-bool regionVectHas( RegionVect &regVect, TokenRegion *region )
-{
- for ( RegionVect::Iter trvi = regVect; trvi.lte(); trvi++ ) {
- if ( *trvi == region )
- return true;
- }
- return false;
-}
-
-void Compiler::addRegion( PdaState *tabState, PdaTrans *tabTrans,
- long pdaKey, bool noPreIgnore, bool noPostIgnore )
-{
- LangEl *langEl = langElIndex[pdaKey];
- if ( langEl != 0 && langEl->type == LangEl::Term ) {
- TokenRegion *region = 0;
- RegionSet *regionSet = 0;
-
- /* If it is not the eof, then use the region associated
- * with the token definition. */
- if ( langEl->isZero ) {
- region = langEl->tokenDef->regionSet->collectIgnore;
- regionSet = langEl->tokenDef->regionSet;
- }
- else if ( !langEl->isEOF && langEl->tokenDef != 0 ) {
- region = langEl->tokenDef->regionSet->tokenIgnore;
- regionSet = langEl->tokenDef->regionSet;
- }
-
- if ( region != 0 ) {
- /* region. */
- TokenRegion *scanRegion = region;
-
- if ( langEl->noPreIgnore )
- scanRegion = regionSet->tokenOnly;
-
- if ( !regionVectHas( tabState->regions, scanRegion ) )
- tabState->regions.append( scanRegion );
-
- /* Pre-region of to state */
- PdaState *toState = tabTrans->toState;
- if ( !langEl->noPostIgnore &&
- regionSet->ignoreOnly != 0 &&
- !regionVectHas( toState->preRegions, regionSet->ignoreOnly ) )
- {
- toState->preRegions.append( regionSet->ignoreOnly );
- }
- }
- }
-}
-
-#if 0
- orderState( tabState, prodState, time ):
- if not tabState.dotSet.find( prodState.dotID )
- tabState.dotSet.insert( prodState.dotID )
- tabTrans = tabState.findMatchingTransition( prodState.getTransition() )
-
- if tabTrans is NonTerminal:
- for production in tabTrans.nonTerm.prodList:
- orderState( tabState, production.startState, time )
-
- for all expandToState in tabTrans.expandToStates:
- for all followTrans in expandToState.transList
- reduceAction = findAction( production.reduction )
- if reduceAction.time is unset:
- reduceAction.time = time++
- end
- end
- end
- end
- end
-
- shiftAction = tabTrans.findAction( shift )
- if shiftAction.time is unset:
- shiftAction.time = time++
- end
-
- orderState( tabTrans.toState, prodTrans.toState, time )
- end
- end
-
- orderState( parseTable.startState, startProduction.startState, 1 )
-#endif
-
-void Compiler::pdaOrderProd( LangEl *rootEl, PdaState *tabState,
- PdaState *srcState, Production *parentDef, long &time )
-{
- assert( srcState->dotSet.length() == 1 );
- if ( tabState->dotSet2.find( srcState->dotSet[0] ) )
- return;
- tabState->dotSet2.insert( srcState->dotSet[0] );
-
- assert( srcState->transMap.length() == 0 || srcState->transMap.length() == 1 );
-
- if ( srcState->transMap.length() == 1 ) {
- TransMap::Iter srcTrans = srcState->transMap;
-
- /* Find the equivalent state in the parser. */
- PdaTrans *tabTrans = tabState->findTrans( srcTrans->key );
-
- /* Recurse into the transition if it is a non-terminal. */
- LangEl *langEl = langElIndex[srcTrans->key];
- if ( langEl != 0 ) {
- if ( langEl->reduceFirst ) {
- /* Use a shortest match ordering for the contents of this
- * nonterminal. Does follows for all productions first, then
- * goes down the productions. */
- for ( LelDefList::Iter expDef = langEl->defList; expDef.lte(); expDef++ ) {
- pdaOrderFollow( rootEl, tabState, tabTrans, srcTrans->value,
- parentDef, expDef, time );
- }
- for ( LelDefList::Iter expDef = langEl->defList; expDef.lte(); expDef++ )
- pdaOrderProd( rootEl, tabState, expDef->fsm->startState, expDef, time );
-
- }
- else {
- /* The default action ordering. For each prod, goes down the
- * prod then sets the follow before going to the next prod. */
- for ( LelDefList::Iter expDef = langEl->defList; expDef.lte(); expDef++ ) {
- pdaOrderProd( rootEl, tabState, expDef->fsm->startState, expDef, time );
-
- pdaOrderFollow( rootEl, tabState, tabTrans, srcTrans->value,
- parentDef, expDef, time );
- }
- }
- }
-
- trySetTime( tabTrans, SHIFT_CODE, time );
-
- /* Now possibly for the dup. */
- if ( langEl != 0 && langEl->termDup != 0 ) {
- PdaTrans *dupTrans = tabState->findTrans( langEl->termDup->id );
- trySetTime( dupTrans, SHIFT_CODE, time );
- }
-
- /* If the items token region is not recorded in the state, do it now. */
- addRegion( tabState, tabTrans, srcTrans->key,
- srcTrans->value->noPreIgnore, srcTrans->value->noPostIgnore );
-
- /* Go over one in the production. */
- pdaOrderProd( rootEl, tabTrans->toState,
- srcTrans->value->toState, parentDef, time );
- }
-}
-
-void Compiler::pdaActionOrder( PdaGraph *pdaGraph, LangElSet &parserEls )
-{
- for ( PdaStateList::Iter state = pdaGraph->stateList; state.lte(); state++ ) {
- assert( (state->stateBits & SB_ISMARKED) == 0 );
-
- /* Traverse the src state's transitions. */
- long last = 0;
- for ( TransMap::Iter trans = state->transMap; trans.lte(); trans++ ) {
- if ( ! trans.first() )
- assert( last < trans->key );
- last = trans->key;
- }
- }
-
- /* Compute the action orderings, record the max value. */
- long time = 1;
- for ( LangElSet::Iter pe = parserEls; pe.lte(); pe++ ) {
- PdaState *startState = (*pe)->rootDef->fsm->startState;
- pdaOrderProd( *pe, (*pe)->startState, startState, (*pe)->rootDef, time );
-
- /* Walk over the start lang el and set the time for shift of
- * the eof action that completes the parse. */
- PdaTrans *overStart = (*pe)->startState->findTrans( (*pe)->id );
- PdaTrans *eofTrans = overStart->toState->findTrans( (*pe)->eofLel->id );
- eofTrans->actOrds[0] = time++;
- }
-
- for ( PdaStateList::Iter state = pdaGraph->stateList; state.lte(); state++ ) {
- if ( state->regions.length() == 0 ) {
- for ( TransMap::Iter tel = state->transMap; tel.lte(); tel++ ) {
- /* There are no regions and EOF leaves the state. Add the eof
- * token region. */
- PdaTrans *trans = tel->value;
- LangEl *lel = langElIndex[trans->lowKey];
- if ( lel != 0 && lel->isEOF )
- state->regions.append( EOF_REGION );
- }
- }
- }
-
- ///* Warn about states with empty token region lists. */
- //for ( PdaStateList::Iter state = pdaGraph->stateList; state.lte(); state++ ) {
- // if ( state->regions.length() == 0 ) {
- // warning() << "state has an empty token region, state: " <<
- // state->stateNum << endl;
- // }
- //}
-
- /* Some actions may not have an ordering. I believe these to be actions
- * that result in a parse error and they arise because the state tables
- * are LALR(1) but the action ordering is LR(1). LALR(1) causes some
- * reductions that lead nowhere. */
- for ( PdaStateList::Iter state = pdaGraph->stateList; state.lte(); state++ ) {
- assert( CmpDotSet::compare( state->dotSet, state->dotSet2 ) == 0 );
- for ( TransMap::Iter tel = state->transMap; tel.lte(); tel++ ) {
- PdaTrans *trans = tel->value;
- /* Check every action has an ordering. */
- for ( ActDataList::Iter adl = trans->actOrds; adl.lte(); adl++ ) {
- if ( *adl == 0 )
- *adl = time++;
- }
- }
- }
-}
-
-void Compiler::advanceReductions( PdaGraph *pdaGraph )
-{
- /* Loop all states. */
- for ( PdaStateList::Iter state = pdaGraph->stateList; state.lte(); state++ ) {
- if ( !state->advanceReductions )
- continue;
-
- bool outHasShift = false;
- ReductionMap outReds;
- LongSet outCommits;
- for ( TransMap::Iter out = state->transMap; out.lte(); out++ ) {
- /* Get the transition from the trans el. */
- if ( out->value->isShift )
- outHasShift = true;
- outReds.insert( out->value->reductions );
- outCommits.insert( out->value->commits );
- }
-
- bool inHasShift = false;
- ReductionMap inReds;
- for ( PdaTransInList::Iter in = state->inRange; in.lte(); in++ ) {
- /* Get the transition from the trans el. */
- if ( in->isShift )
- inHasShift = true;
- inReds.insert( in->reductions );
- }
-
- if ( !outHasShift && outReds.length() == 1 &&
- inHasShift && inReds.length() == 0 )
- {
- //cerr << "moving reduction to shift" << endl;
-
- /* Move the reduction to all in transitions. */
- for ( PdaTransInList::Iter in = state->inRange; in.lte(); in++ ) {
- assert( in->actions.length() == 1 );
- assert( in->actions[0] == SHIFT_CODE );
- in->actions[0] = makeReduceCode( outReds[0].key, true );
- in->afterShiftCommits.insert( outCommits );
- }
-
- /*
- * Remove all transitions out of the state.
- */
-
- /* Detach out range transitions. */
- for ( TransMap::Iter trans = state->transMap; trans.lte(); trans++ ) {
- pdaGraph->detachTrans( state, trans->value->toState, trans->value );
- delete trans->value;
- }
- state->transMap.empty();
-
- /* Redirect all the in transitions to the actionDestState. */
- pdaGraph->inTransMove( actionDestState, state );
- }
- }
-
- pdaGraph->removeUnreachableStates();
-}
-
-void Compiler::sortActions( PdaGraph *pdaGraph )
-{
- /* Sort the actions. */
- for ( PdaStateList::Iter state = pdaGraph->stateList; state.lte(); state++ ) {
- assert( CmpDotSet::compare( state->dotSet, state->dotSet2 ) == 0 );
- for ( TransMap::Iter tel = state->transMap; tel.lte(); tel++ ) {
- PdaTrans *trans = tel->value;
-
- /* Sort by the action ords. */
- ActDataList actions( trans->actions );
- ActDataList actOrds( trans->actOrds );
- ActDataList actPriors( trans->actPriors );
- trans->actions.empty();
- trans->actOrds.empty();
- trans->actPriors.empty();
- while ( actOrds.length() > 0 ) {
- int min = 0;
- for ( int i = 1; i < actOrds.length(); i++ ) {
- if ( actPriors[i] > actPriors[min] ||
- (actPriors[i] == actPriors[min] &&
- actOrds[i] < actOrds[min] ) )
- {
- min = i;
- }
- }
- trans->actions.append( actions[min] );
- trans->actOrds.append( actOrds[min] );
- trans->actPriors.append( actPriors[min] );
- actions.remove(min);
- actOrds.remove(min);
- actPriors.remove(min);
- }
-
- if ( branchPointInfo && trans->actions.length() > 1 ) {
- cerr << "info: branch point"
- << " state: " << state->stateNum
- << " trans: ";
- LangEl *lel = langElIndex[trans->lowKey];
- if ( lel == 0 )
- cerr << (char)trans->lowKey << endl;
- else
- cerr << lel->lit << endl;
-
- for ( ActDataList::Iter act = trans->actions; act.lte(); act++ ) {
- switch ( *act & 0x3 ) {
- case 1:
- cerr << " shift" << endl;
- break;
- case 2:
- cerr << " reduce " <<
- prodIdIndex[(*act >> 2)]->data << endl;
- break;
- case 3:
- cerr << " shift-reduce" << endl;
- break;
- }
- }
- }
-
- /* Verify that shifts of nonterminals don't have any branch
- * points or commits. */
- if ( trans->lowKey >= firstNonTermId ) {
- if ( trans->actions.length() != 1 ||
- (trans->actions[0] & 0x3) != 1 )
- {
- error() << "TRANS ON NONTERMINAL is something "
- "other than a shift" << endl;
- }
- if ( trans->commits.length() > 0 )
- error() << "TRANS ON NONTERMINAL has a commit" << endl;
- }
-
- /* TODO: Shift-reduces are optimizations. Verify that
- * shift-reduces exist only if they don't entail a conflict. */
- }
- }
-}
-
-void Compiler::reduceActions( PdaGraph *pdaGraph )
-{
- /* Reduce the actions. */
- for ( PdaStateList::Iter state = pdaGraph->stateList; state.lte(); state++ ) {
- for ( TransMap::Iter tel = state->transMap; tel.lte(); tel++ ) {
- PdaTrans *trans = tel->value;
- PdaActionSetEl *inSet;
-
- int commitLen = trans->commits.length() > 0 ?
- trans->commits[trans->commits.length()-1] : 0;
-
- if ( trans->afterShiftCommits.length() > 0 ) {
- int afterShiftCommit = trans->afterShiftCommits[
- trans->afterShiftCommits.length()-1];
-
- if ( commitLen > 0 && commitLen+1 > afterShiftCommit )
- commitLen = ( commitLen + 1 );
- else
- commitLen = afterShiftCommit;
- }
- else {
- commitLen = commitLen * -1;
- }
-
- //if ( commitLen != 0 ) {
- // cerr << "FINAL ACTION COMMIT LEN: " << commitLen << endl;
- //}
-
- pdaGraph->actionSet.insert( ActionData( trans->toState->stateNum,
- trans->actions, commitLen ), &inSet );
- trans->actionSetEl = inSet;
- }
- }
-}
-
-void Compiler::computeAdvanceReductions( LangEl *langEl, PdaGraph *pdaGraph )
-{
- /* Get the entry into the graph and traverse over the root. The resulting
- * state can have eof, nothing else can. */
- PdaState *overStart = pdaGraph->followFsm(
- langEl->startState,
- langEl->rootDef->fsm );
-
- /* The graph must reduce to root all on it's own. It cannot depend on
- * require EOF. */
- for ( PdaStateList::Iter st = pdaGraph->stateList; st.lte(); st++ ) {
- if ( st == overStart )
- continue;
-
- for ( TransMap::Iter tr = st->transMap; tr.lte(); tr++ ) {
- if ( tr->value->lowKey == langEl->eofLel->id )
- st->advanceReductions = true;
- }
- }
-}
-
-void Compiler::verifyParseStopGrammar( LangEl *langEl, PdaGraph *pdaGraph )
-{
- /* Get the entry into the graph and traverse over the root. The resulting
- * state can have eof, nothing else can. */
- PdaState *overStart = pdaGraph->followFsm(
- langEl->startState,
- langEl->rootDef->fsm );
-
- /* The graph must reduce to root all on it's own. It cannot depend on
- * require EOF. */
- for ( PdaStateList::Iter st = pdaGraph->stateList; st.lte(); st++ ) {
- if ( st == overStart )
- continue;
-
- for ( TransMap::Iter tr = st->transMap; tr.lte(); tr++ ) {
- if ( tr->value->lowKey == langEl->eofLel->id ) {
- /* This needs a better error message. Appears to be voodoo. */
- error() << "grammar is not usable with parse_stop" << endp;
- }
- }
- }
-}
-
-LangEl *Compiler::predOf( PdaTrans *trans, long action )
-{
- LangEl *lel;
- if ( action == SHIFT_CODE )
- lel = langElIndex[trans->lowKey];
- else
- lel = prodIdIndex[action >> 2]->predOf;
- return lel;
-}
-
-
-bool Compiler::precedenceSwap( long action1, long action2, LangEl *l1, LangEl *l2 )
-{
- bool swap = false;
- if ( l2->predValue > l1->predValue )
- swap = true;
- else if ( l1->predValue == l2->predValue ) {
- if ( l1->predType == PredLeft && action1 == SHIFT_CODE )
- swap = true;
- else if ( l1->predType == PredRight && action2 == SHIFT_CODE )
- swap = true;
- }
- return swap;
-}
-
-bool Compiler::precedenceRemoveBoth( LangEl *l1, LangEl *l2 )
-{
- if ( l1->predValue == l2->predValue && l1->predType == PredNonassoc )
- return true;
- return false;
-}
-
-void Compiler::resolvePrecedence( PdaGraph *pdaGraph )
-{
- for ( PdaStateList::Iter state = pdaGraph->stateList; state.lte(); state++ ) {
- assert( CmpDotSet::compare( state->dotSet, state->dotSet2 ) == 0 );
-
- for ( long t = 0; t < state->transMap.length(); /* increment at end */ ) {
- PdaTrans *trans = state->transMap[t].value;
-
-again:
- /* Find action with precedence. */
- for ( int i = 0; i < trans->actions.length(); i++ ) {
- LangEl *li = predOf( trans, trans->actions[i] );
-
- if ( li != 0 && li->predType != PredNone ) {
- /* Find another action with precedence. */
- for ( int j = i+1; j < trans->actions.length(); j++ ) {
- LangEl *lj = predOf( trans, trans->actions[j] );
-
- if ( lj != 0 && lj->predType != PredNone ) {
- /* Conflict to check. */
- bool swap = precedenceSwap( trans->actions[i],
- trans->actions[j], li, lj );
-
- if ( swap ) {
- long t = trans->actions[i];
- trans->actions[i] = trans->actions[j];
- trans->actions[j] = t;
- }
-
- trans->actions.remove( j );
- if ( precedenceRemoveBoth( li, lj ) )
- trans->actions.remove( i );
-
- goto again;
- }
- }
- }
- }
-
- /* If there are still actions then move to the next one. If not,
- * (due to nonassoc) then remove the transition. */
- if ( trans->actions.length() > 0 )
- t += 1;
- else
- state->transMap.vremove( t );
- }
- }
-}
-
-void Compiler::analyzeMachine( PdaGraph *pdaGraph, LangElSet &parserEls )
-{
- pdaGraph->maxState = pdaGraph->stateList.length() - 1;
- pdaGraph->maxLelId = nextLelId - 1;
- pdaGraph->maxOffset = pdaGraph->stateList.length() * pdaGraph->maxLelId;
-
- for ( PdaStateList::Iter state = pdaGraph->stateList; state.lte(); state++ ) {
- for ( TransMap::Iter trans = state->transMap; trans.lte(); trans++ ) {
- if ( trans->value->isShift ) {
- trans->value->actions.append( SHIFT_CODE );
- trans->value->actPriors.append( trans->value->shiftPrior );
- }
- for ( ReductionMap::Iter red = trans->value->reductions; red.lte(); red++ ) {
- trans->value->actions.append( makeReduceCode( red->key, false ) );
- trans->value->actPriors.append( red->value );
- }
- trans->value->actOrds.appendDup( 0, trans->value->actions.length() );
- }
- }
-
- pdaActionOrder( pdaGraph, parserEls );
- sortActions( pdaGraph );
- resolvePrecedence( pdaGraph );
-
- /* Verify that any type we parse_stop can actually be parsed that way. */
- for ( LangElSet::Iter pe = parserEls; pe.lte(); pe++ ) {
- LangEl *lel = *pe;
- if ( lel->parseStop )
- computeAdvanceReductions(lel , pdaGraph);
- }
-
- advanceReductions( pdaGraph );
- pdaGraph->setStateNumbers();
- reduceActions( pdaGraph );
-
- /* Set the action ids. */
- int actionSetId = 0;
- for ( PdaActionSet::Iter asi = pdaGraph->actionSet; asi.lte(); asi++ )
- asi->key.id = actionSetId++;
-
- /* Get the max index. */
- pdaGraph->maxIndex = actionSetId - 1;
-
- /* Compute the max prod length. */
- pdaGraph->maxProdLen = 0;
- for ( DefList::Iter prod = prodList; prod.lte(); prod++ ) {
- if ( (unsigned)prod->fsmLength > pdaGraph->maxProdLen )
- pdaGraph->maxProdLen = prod->fsmLength;
- }
-
- /* Asserts that any transition with a nonterminal has a single action
- * which is either a shift or a shift-reduce. */
- for ( PdaStateList::Iter state = pdaGraph->stateList; state.lte(); state++ ) {
- for ( TransMap::Iter trans = state->transMap; trans.lte(); trans++ ) {
- LangEl *langEl = langElIndex[trans->value->lowKey];
- if ( langEl != 0 && langEl->type == LangEl::NonTerm ) {
- assert( trans->value->actions.length() == 1 );
- assert( trans->value->actions[0] == SHIFT_CODE ||
- (trans->value->actions[0] & 0x3) == SHIFT_REDUCE_CODE );
- }
- }
- }
-
- /* Assert that shift reduces always appear on their own. */
- for ( PdaStateList::Iter state = pdaGraph->stateList; state.lte(); state++ ) {
- for ( TransMap::Iter trans = state->transMap; trans.lte(); trans++ ) {
- for ( ActDataList::Iter act = trans->value->actions; act.lte(); act++ ) {
- if ( (*act & 0x3) == SHIFT_REDUCE_CODE )
- assert( trans->value->actions.length() == 1 );
- }
- }
- }
-
- /* Verify that any type we parse_stop can actually be parsed that way. */
- for ( LangElSet::Iter pe = parserEls; pe.lte(); pe++ ) {
- LangEl *lel = *pe;
- if ( lel->parseStop )
- verifyParseStopGrammar(lel , pdaGraph);
- }
-}
-
-void Compiler::wrapNonTerminals()
-{
- /* Make a language element that will be used to make the root productions.
- * These are used for making parsers rooted at any production (including
- * the start symbol). */
- rootLangEl = declareLangEl( this, rootNamespace, "_root", LangEl::NonTerm );
-
- for ( LelList::Iter lel = langEls; lel.lte(); lel++ ) {
- /* Make a single production used when the lel is a root. */
- ProdElList *prodElList = makeProdElList( lel );
- lel->rootDef = Production::cons( InputLoc(), rootLangEl,
- prodElList, String(), false, 0,
- prodList.length(), rootLangEl->defList.length() );
- prodList.append( lel->rootDef );
- rootLangEl->defList.append( lel->rootDef );
-
- /* First resolve. */
- for ( ProdElList::Iter prodEl = *prodElList; prodEl.lte(); prodEl++ )
- resolveProdEl( prodEl );
- }
-}
-
-bool Compiler::makeNonTermFirstSetProd( Production *prod, PdaState *state )
-{
- bool modified = false;
- for ( TransMap::Iter trans = state->transMap; trans.lte(); trans++ ) {
- if ( trans->key >= firstNonTermId ) {
- long *inserted = prod->nonTermFirstSet.insert( trans->key );
- if ( inserted != 0 )
- modified = true;
-
- bool hasEpsilon = false;
- LangEl *lel = langElIndex[trans->key];
- for ( LelDefList::Iter ldef = lel->defList; ldef.lte(); ldef++ ) {
- for ( ProdIdSet::Iter pid = ldef->nonTermFirstSet;
- pid.lte(); pid++ )
- {
- if ( *pid == -1 )
- hasEpsilon = true;
- else {
- long *inserted = prod->nonTermFirstSet.insert( *pid );
- if ( inserted != 0 )
- modified = true;
- }
- }
- }
-
- if ( hasEpsilon ) {
- if ( trans->value->toState->isFinState() ) {
- long *inserted = prod->nonTermFirstSet.insert( -1 );
- if ( inserted != 0 )
- modified = true;
- }
-
- bool lmod = makeNonTermFirstSetProd( prod, trans->value->toState );
- if ( lmod )
- modified = true;
- }
- }
- }
- return modified;
-}
-
-
-void Compiler::makeNonTermFirstSets()
-{
- bool modified = true;
- while ( modified ) {
- modified = false;
- for ( DefList::Iter prod = prodList; prod.lte(); prod++ ) {
- if ( prod->fsm->startState->isFinState() ) {
- long *inserted = prod->nonTermFirstSet.insert( -1 );
- if ( inserted != 0 )
- modified = true;
- }
-
- bool lmod = makeNonTermFirstSetProd( prod, prod->fsm->startState );
- if ( lmod )
- modified = true;
- }
- }
-
- for ( DefList::Iter prod = prodList; prod.lte(); prod++ ) {
- if ( prod->nonTermFirstSet.find( prod->prodName->id ) )
- prod->isLeftRec = true;
- }
-}
-
-void Compiler::printNonTermFirstSets()
-{
- for ( DefList::Iter prod = prodList; prod.lte(); prod++ ) {
- cerr << prod->data << ": ";
- for ( ProdIdSet::Iter pid = prod->nonTermFirstSet; pid.lte(); pid++ )
- {
- if ( *pid < 0 )
- cerr << " <EPSILON>";
- else {
- LangEl *lel = langElIndex[*pid];
- cerr << " " << lel->name;
- }
- }
- cerr << endl;
-
- if ( prod->isLeftRec )
- cerr << "PROD IS LEFT REC: " << prod->data << endl;
- }
-}
-
-bool Compiler::makeFirstSetProd( Production *prod, PdaState *state )
-{
- bool modified = false;
- for ( TransMap::Iter trans = state->transMap; trans.lte(); trans++ ) {
- if ( trans->key < firstNonTermId ) {
- long *inserted = prod->firstSet.insert( trans->key );
- if ( inserted != 0 )
- modified = true;
- }
- else {
- long *inserted = prod->firstSet.insert( trans->key );
- if ( inserted != 0 )
- modified = true;
-
- LangEl *klangEl = langElIndex[trans->key];
- if ( klangEl != 0 && klangEl->termDup != 0 ) {
- long *inserted2 = prod->firstSet.insert( klangEl->termDup->id );
- if ( inserted2 != 0 )
- modified = true;
- }
-
- bool hasEpsilon = false;
- LangEl *lel = langElIndex[trans->key];
- for ( LelDefList::Iter ldef = lel->defList; ldef.lte(); ldef++ ) {
- for ( ProdIdSet::Iter pid = ldef->firstSet;
- pid.lte(); pid++ )
- {
- if ( *pid == -1 )
- hasEpsilon = true;
- else {
- long *inserted = prod->firstSet.insert( *pid );
- if ( inserted != 0 )
- modified = true;
- }
- }
- }
-
- if ( hasEpsilon ) {
- if ( trans->value->toState->isFinState() ) {
- long *inserted = prod->firstSet.insert( -1 );
- if ( inserted != 0 )
- modified = true;
- }
-
- bool lmod = makeFirstSetProd( prod, trans->value->toState );
- if ( lmod )
- modified = true;
- }
- }
- }
- return modified;
-}
-
-
-void Compiler::makeFirstSets()
-{
- bool modified = true;
- while ( modified ) {
- modified = false;
- for ( DefList::Iter prod = prodList; prod.lte(); prod++ ) {
- if ( prod->fsm->startState->isFinState() ) {
- long *inserted = prod->firstSet.insert( -1 );
- if ( inserted != 0 )
- modified = true;
- }
-
- bool lmod = makeFirstSetProd( prod, prod->fsm->startState );
- if ( lmod )
- modified = true;
- }
- }
-}
-
-void Compiler::printFirstSets()
-{
- for ( DefList::Iter prod = prodList; prod.lte(); prod++ ) {
- cerr << prod->data << ": ";
- for ( ProdIdSet::Iter pid = prod->firstSet; pid.lte(); pid++ )
- {
- if ( *pid < 0 )
- cerr << " <EPSILON>";
- else {
- LangEl *lel = langElIndex[*pid];
- if ( lel != 0 )
- cerr << endl << " " << lel->name;
- else
- cerr << endl << " " << *pid;
- }
- }
- cerr << endl;
- }
-}
-
-void Compiler::insertUniqueEmptyProductions()
-{
- int limit = prodList.length();
- for ( DefList::Iter prod = prodList; prod.lte(); prod++ ) {
- if ( prod->prodId == limit )
- break;
-
- /* Get a language element. */
- char name[20];
- sprintf(name, "U%li", prodList.length());
- LangEl *prodName = addLangEl( this, rootNamespace, name, LangEl::NonTerm );
- Production *newDef = Production::cons( InputLoc(), prodName,
- 0, String(), false, 0, prodList.length(), prodName->defList.length() );
- prodName->defList.append( newDef );
- prodList.append( newDef );
-
- prod->uniqueEmptyLeader = prodName;
- }
-}
-
-struct local_info *Compiler::makeLocalInfo( Locals &locals )
-{
- struct local_info *localInfo = new local_info[locals.locals.length()];
- memset( localInfo, 0, sizeof(struct local_info) * locals.locals.length() );
-
- for ( Vector<LocalLoc>::Iter l = locals.locals; l.lte(); l++ ) {
- localInfo[l.pos()].type = (int) l->type;
- localInfo[l.pos()].offset = l->offset;
- }
- return localInfo;
-}
-
-short *Compiler::makeTrees( ObjectDef *objectDef, int &numTrees )
-{
- numTrees = 0;
- for ( FieldList::Iter of = objectDef->fieldList; of.lte(); of++ ) {
- if ( of->value->exists() ) {
- UniqueType *ut = of->value->typeRef->resolveType( this );
- if ( ut->typeId == TYPE_TREE )
- numTrees += 1;
- }
- }
-
- short *trees = new short[numTrees];
- memset( trees, 0, sizeof(short) * numTrees );
-
- short pos = 0;
- for ( FieldList::Iter of = objectDef->fieldList; of.lte(); of++ ) {
- if ( of->value->exists() ) {
- UniqueType *ut = of->value->typeRef->resolveType( this );
- if ( ut->typeId == TYPE_TREE ) {
- trees[pos] = of->value->offset;
- pos += 1;
- }
- }
- }
-
- return trees;
-}
-
-
-void Compiler::makeRuntimeData()
-{
- long count = 0;
-
- /*
- * ProdLengths
- * ProdLhsIs
- * ProdNames
- * ProdCodeBlocks
- * ProdCodeBlockLens
- */
-
- runtimeData->frame_info = new frame_info[nextFrameId];
- runtimeData->num_frames = nextFrameId;
- memset( runtimeData->frame_info, 0, sizeof(struct frame_info) * nextFrameId );
-
- /*
- * Init code block.
- */
- if ( rootCodeBlock == 0 ) {
- runtimeData->root_code = 0;
- runtimeData->root_code_len = 0;
- runtimeData->root_frame_id = 0;
- }
- else {
- runtimeData->root_code = rootCodeBlock->codeWC.data;
- runtimeData->root_code_len = rootCodeBlock->codeWC.length();
- runtimeData->root_frame_id = rootCodeBlock->frameId;
- }
-
- runtimeData->frame_info[rootCodeBlock->frameId].codeWV = 0;
- runtimeData->frame_info[rootCodeBlock->frameId].codeLenWV = 0;
-
- runtimeData->frame_info[rootCodeBlock->frameId].locals = makeLocalInfo( rootCodeBlock->locals );
- runtimeData->frame_info[rootCodeBlock->frameId].locals_len = rootCodeBlock->locals.locals.length();
-
- runtimeData->frame_info[rootCodeBlock->frameId].frame_size = rootLocalFrame->size();
- runtimeData->frame_info[rootCodeBlock->frameId].arg_size = 0;
- runtimeData->frame_info[rootCodeBlock->frameId].ret_tree = false;
-
- /*
- * prodInfo
- */
- count = prodList.length();
- runtimeData->prod_info = new prod_info[count];
- runtimeData->num_prods = count;
-
- count = 0;
- for ( DefList::Iter prod = prodList; prod.lte(); prod++ ) {
- runtimeData->prod_info[count].lhs_id = prod->prodName->id;
- runtimeData->prod_info[count].prod_num = prod->prodNum;
- runtimeData->prod_info[count].length = prod->fsmLength;
- runtimeData->prod_info[count].name = prod->data;
- runtimeData->prod_info[count].frame_id = -1;
-
- CodeBlock *block = prod->redBlock;
- if ( block != 0 ) {
- runtimeData->prod_info[count].frame_id = block->frameId;
- runtimeData->frame_info[block->frameId].codeWV = block->codeWV.data;
- runtimeData->frame_info[block->frameId].codeLenWV = block->codeWV.length();
-
- runtimeData->frame_info[block->frameId].locals = makeLocalInfo( block->locals );
- runtimeData->frame_info[block->frameId].locals_len = block->locals.locals.length();
-
- runtimeData->frame_info[block->frameId].frame_size = block->localFrame->size();
- runtimeData->frame_info[block->frameId].arg_size = 0;
- runtimeData->frame_info[block->frameId].ret_tree = false;
- }
-
- runtimeData->prod_info[count].lhs_upref = true;
- runtimeData->prod_info[count].copy = prod->copy.data;
- runtimeData->prod_info[count].copy_len = prod->copy.length() / 2;
- count += 1;
- }
-
- /*
- * regionInfo
- */
- runtimeData->num_regions = regionList.length()+1;
- runtimeData->region_info = new region_info[runtimeData->num_regions];
- memset( runtimeData->region_info, 0,
- sizeof(struct region_info) * runtimeData->num_regions );
-
- runtimeData->region_info[0].default_token = -1;
- runtimeData->region_info[0].eof_frame_id = -1;
- runtimeData->region_info[0].ci_lel_id = 0;
-
- for ( RegionList::Iter reg = regionList; reg.lte(); reg++ ) {
- long regId = reg->id+1;
- runtimeData->region_info[regId].default_token =
- reg->impl->defaultTokenInstance == 0 ?
- -1 :
- reg->impl->defaultTokenInstance->tokenDef->tdLangEl->id;
- runtimeData->region_info[regId].eof_frame_id = -1;
- runtimeData->region_info[regId].ci_lel_id = reg->zeroLel != 0 ? reg->zeroLel->id : 0;
-
- CodeBlock *block = reg->preEofBlock;
- if ( block != 0 ) {
- runtimeData->region_info[regId].eof_frame_id = block->frameId;
- runtimeData->frame_info[block->frameId].codeWV = block->codeWV.data;
- runtimeData->frame_info[block->frameId].codeLenWV = block->codeWV.length();
-
- runtimeData->frame_info[block->frameId].locals = makeLocalInfo( block->locals );
- runtimeData->frame_info[block->frameId].locals_len = block->locals.locals.length();
-
- runtimeData->frame_info[block->frameId].frame_size = block->localFrame->size();
- runtimeData->frame_info[block->frameId].arg_size = 0;
- runtimeData->frame_info[block->frameId].ret_tree = false;
- }
- }
-
- /*
- * lelInfo
- */
-
- count = nextLelId;
- runtimeData->lel_info = new lang_el_info[count];
- runtimeData->num_lang_els = count;
- memset( runtimeData->lel_info, 0, sizeof(struct lang_el_info)*count );
-
- for ( int i = 0; i < nextLelId; i++ ) {
- LangEl *lel = langElIndex[i];
- if ( lel != 0 ) {
- runtimeData->lel_info[i].name = lel->fullLit;
- runtimeData->lel_info[i].xml_tag = lel->xmlTag;
- runtimeData->lel_info[i].repeat = lel->isRepeat;
- runtimeData->lel_info[i].list = lel->isList;
- runtimeData->lel_info[i].literal = lel->isLiteral;
- runtimeData->lel_info[i].ignore = lel->isIgnore;
- runtimeData->lel_info[i].frame_id = -1;
-
- CodeBlock *block = lel->transBlock;
- if ( block != 0 ) {
- runtimeData->lel_info[i].frame_id = block->frameId;
- runtimeData->frame_info[block->frameId].codeWV = block->codeWV.data;
- runtimeData->frame_info[block->frameId].codeLenWV = block->codeWV.length();
-
- runtimeData->frame_info[block->frameId].locals = makeLocalInfo( block->locals );
- runtimeData->frame_info[block->frameId].locals_len = block->locals.locals.length();
-
- runtimeData->frame_info[block->frameId].frame_size = block->localFrame->size();
- runtimeData->frame_info[block->frameId].arg_size = 0;
- runtimeData->frame_info[block->frameId].ret_tree = false;
- }
-
- runtimeData->lel_info[i].object_type_id =
- lel->objectDef == 0 ? 0 : lel->objectDef->id;
- runtimeData->lel_info[i].ofi_offset = lel->ofiOffset;
- runtimeData->lel_info[i].object_length =
- lel->objectDef != 0 ? lel->objectDef->size() : 0;
-
-// runtimeData->lelInfo[i].contextTypeId = 0;
-// lel->context == 0 ? 0 : lel->context->contextObjDef->id;
-// runtimeData->lelInfo[i].contextLength = 0; //lel->context == 0 ? 0 :
-// lel->context->contextObjDef->size();
-// if ( lel->context != 0 ) {
-// cout << "type: " << runtimeData->lelInfo[i].contextTypeId << " length: " <<
-// runtimeData->lelInfo[i].contextLength << endl;
-// }
-
- runtimeData->lel_info[i].term_dup_id = lel->termDup == 0 ? 0 : lel->termDup->id;
-
- if ( lel->tokenDef != 0 && lel->tokenDef->join != 0 &&
- lel->tokenDef->join->context != 0 )
- runtimeData->lel_info[i].mark_id = lel->tokenDef->join->mark->markId;
- else
- runtimeData->lel_info[i].mark_id = -1;
-
- runtimeData->lel_info[i].num_capture_attr = 0;
- }
- else {
- memset(&runtimeData->lel_info[i], 0, sizeof(struct lang_el_info) );
- runtimeData->lel_info[i].name = "__UNUSED";
- runtimeData->lel_info[i].xml_tag = "__UNUSED";
- runtimeData->lel_info[i].frame_id = -1;
- }
- }
-
- /*
- * struct_el_info
- */
-
- count = structEls.length();
- runtimeData->sel_info = new struct_el_info[count];
- runtimeData->num_struct_els = count;
- memset( runtimeData->sel_info, 0, sizeof(struct struct_el_info)*count );
- StructElList::Iter sel = structEls;
- for ( int i = 0; i < count; i++, sel++ ) {
- int treesLen;
- runtimeData->sel_info[i].size = sel->structDef->objectDef->size();
- runtimeData->sel_info[i].trees = makeTrees( sel->structDef->objectDef, treesLen );
- runtimeData->sel_info[i].trees_len = treesLen;
- }
-
- /*
- * function_info
- */
- count = functionList.length();
-
- runtimeData->function_info = new function_info[count];
- runtimeData->num_functions = count;
- memset( runtimeData->function_info, 0, sizeof(struct function_info)*count );
- for ( FunctionList::Iter func = functionList; func.lte(); func++ ) {
-
- runtimeData->function_info[func->funcId].frame_id = -1;
-
- CodeBlock *block = func->codeBlock;
- if ( block != 0 ) {
- runtimeData->function_info[func->funcId].frame_id = block->frameId;
-
- /* Name. */
- runtimeData->frame_info[block->frameId].name = func->name;
-
- /* Code. */
- runtimeData->frame_info[block->frameId].codeWV = block->codeWV.data;
- runtimeData->frame_info[block->frameId].codeLenWV = block->codeWV.length();
- runtimeData->frame_info[block->frameId].codeWC = block->codeWC.data;
- runtimeData->frame_info[block->frameId].codeLenWC = block->codeWC.length();
-
- /* Locals. */
- runtimeData->frame_info[block->frameId].locals = makeLocalInfo( block->locals );
- runtimeData->frame_info[block->frameId].locals_len = block->locals.locals.length();
-
- /* Meta. */
- runtimeData->frame_info[block->frameId].frame_size = func->localFrame->size();
- runtimeData->frame_info[block->frameId].arg_size = func->paramListSize;
-
- bool retTree = false;
- if ( func->typeRef ) {
- UniqueType *ut = func->typeRef->resolveType( this );
- retTree = ut->tree();
- }
- runtimeData->frame_info[block->frameId].ret_tree = retTree;
- }
-
- runtimeData->function_info[func->funcId].frame_size = func->localFrame->size();
- runtimeData->function_info[func->funcId].arg_size = func->paramListSize;
- }
-
- /*
- * pat_cons_info
- */
-
- /* Filled in later after patterns are parsed. */
- runtimeData->pat_repl_info = new pat_cons_info[nextPatConsId];
- memset( runtimeData->pat_repl_info, 0, sizeof(struct pat_cons_info) * nextPatConsId );
- runtimeData->num_patterns = nextPatConsId;
- runtimeData->pat_repl_nodes = 0;
- runtimeData->num_pattern_nodes = 0;
-
-
- /*
- * generic_info
- */
- count = 1;
- for ( NamespaceList::Iter nspace = namespaceList; nspace.lte(); nspace++ )
- count += nspace->genericList.length();
- assert( count == nextGenericId );
-
- runtimeData->generic_info = new generic_info[count];
- runtimeData->num_generics = count;
- memset( &runtimeData->generic_info[0], 0, sizeof(struct generic_info) );
- for ( NamespaceList::Iter nspace = namespaceList; nspace.lte(); nspace++ ) {
- for ( GenericList::Iter gen = nspace->genericList; gen.lte(); gen++ ) {
- runtimeData->generic_info[gen->id].type = gen->typeId;
-
- runtimeData->generic_info[gen->id].el_struct_id =
- ( gen->typeId == GEN_MAP || gen->typeId == GEN_LIST ) ?
- gen->elUt->structEl->id : -1;
- runtimeData->generic_info[gen->id].el_offset =
- gen->el != 0 ? gen->el->offset : -1;
-
- runtimeData->generic_info[gen->id].key_type =
- gen->keyUt != 0 ? gen->keyUt->typeId : TYPE_NOTYPE;
- runtimeData->generic_info[gen->id].key_offset = 0;
-
- runtimeData->generic_info[gen->id].value_type =
- gen->valueUt != 0 ? gen->valueUt->typeId : TYPE_NOTYPE;
- runtimeData->generic_info[gen->id].value_offset = 0;
-
- runtimeData->generic_info[gen->id].parser_id =
- gen->typeId == GEN_PARSER ? gen->elUt->langEl->parserId : -1;
- }
- }
-
- runtimeData->argv_generic_id = argvTypeRef->generic->id;
- runtimeData->stds_generic_id = stdsTypeRef->generic->id;
-
- /*
- * Literals
- */
- runtimeData->num_literals = literalStrings.length();
- runtimeData->litdata = new const char *[literalStrings.length()];
- runtimeData->litlen = new long [literalStrings.length()];
- runtimeData->literals = 0;
- for ( StringMap::Iter el = literalStrings; el.lte(); el++ ) {
- /* Data. */
- char *data = new char[el->key.length()+1];
- memcpy( data, el->key.data, el->key.length() );
- data[el->key.length()] = 0;
- runtimeData->litdata[el->value] = data;
-
- /* Length. */
- runtimeData->litlen[el->value] = el->key.length();
- }
-
- /* Captured attributes. Loop over tokens and count first. */
- long numCapturedAttr = 0;
-// for ( RegionList::Iter reg = regionList; reg.lte(); reg++ ) {
-// for ( TokenInstanceListReg::Iter td = reg->tokenInstanceList; td.lte(); td++ )
-// numCapturedAttr += td->reCaptureVect.length();
-// }
- runtimeData->capture_attr = new CaptureAttr[numCapturedAttr];
- runtimeData->num_captured_attr = numCapturedAttr;
- memset( runtimeData->capture_attr, 0, sizeof( CaptureAttr ) * numCapturedAttr );
-
- count = 0;
-// for ( RegionList::Iter reg = regionList; reg.lte(); reg++ ) {
-// for ( TokenInstanceListReg::Iter td = reg->tokenInstanceList; td.lte(); td++ ) {
-// runtimeData->lelInfo[td->token->id].captureAttr = count;
-// runtimeData->lelInfo[td->token->id].numCaptureAttr = td->reCaptureVect.length();
-// for ( ReCaptureVect::Iter c = td->reCaptureVect; c.lte(); c++ ) {
-// runtimeData->captureAttr[count].mark_enter = c->markEnter->markId;
-// runtimeData->captureAttr[count].mark_leave = c->markLeave->markId;
-// runtimeData->captureAttr[count].offset = c->objField->offset;
-//
-// count += 1;
-// }
-// }
-// }
-
- runtimeData->fsm_tables = fsmTables;
- runtimeData->pda_tables = pdaTables;
-
- /* FIXME: need a parser descriptor. */
- runtimeData->start_states = new int[nextParserId];
- runtimeData->eof_lel_ids = new int[nextParserId];
- runtimeData->parser_lel_ids = new int[nextParserId];
- runtimeData->num_parsers = nextParserId;
- for ( LelList::Iter lel = langEls; lel.lte(); lel++ ) {
- if ( lel->parserId >= 0 ) {
- runtimeData->start_states[lel->parserId] = lel->startState->stateNum;
- runtimeData->eof_lel_ids[lel->parserId] = lel->eofLel->id;
- runtimeData->parser_lel_ids[lel->parserId] = lel->id;
- }
- }
-
- runtimeData->global_size = globalObjectDef->size();
-
- /*
- * Boundary between terms and non-terms.
- */
- runtimeData->first_non_term_id = firstNonTermId;
-
- /*
- * Boundary between trees and structs
- */
- runtimeData->first_struct_el_id = firstStructElId;
-
- /* Special trees. */
- runtimeData->integer_id = -1; //intLangEl->id;
- runtimeData->string_id = strLangEl->id;
- runtimeData->any_id = anyLangEl->id;
- runtimeData->eof_id = 0; //eofLangEl->id;
- runtimeData->no_token_id = noTokenLangEl->id;
- runtimeData->global_id = globalSel->id;
- runtimeData->argv_el_id = argvElSel->id;
- runtimeData->stds_el_id = stdsElSel->id;
- runtimeData->struct_inbuilt_id = structInbuiltId;
- runtimeData->struct_stream_id = structStreamId;
- runtimeData->struct_input_id = structInputId;
-
- runtimeData->fsm_execute = &internalFsmExecute;
- runtimeData->send_named_lang_el = &internalSendNamedLangEl;
- runtimeData->init_bindings = &internalInitBindings;
- runtimeData->pop_binding = &internalPopBinding;
-
- runtimeData->host_call = &internal_host_call;
- runtimeData->commit_reduce_forward = &internal_commit_reduce_forward;
- runtimeData->commit_union_sz = &internal_commit_union_sz;
- runtimeData->init_need = &internal_init_need;
- runtimeData->reducer_need_tok = &internal_reducer_need_tok;
- runtimeData->reducer_need_ign = &internal_reducer_need_ign;
-}
-
-/* Borrow alg->state for mapsTo. */
-void countNodes( program_t *prg, int &count, parse_tree_t *parseTree, kid_t *kid )
-{
- if ( kid != 0 ) {
- count += 1;
-
- /* Should't have to recurse here. */
- tree_t *ignoreList = tree_left_ignore( prg, kid->tree );
- if ( ignoreList != 0 ) {
- kid_t *ignore = ignoreList->child;
- while ( ignore != 0 ) {
- count += 1;
- ignore = ignore->next;
- }
- }
-
- ignoreList = tree_right_ignore( prg, kid->tree );
- if ( ignoreList != 0 ) {
- kid_t *ignore = ignoreList->child;
- while ( ignore != 0 ) {
- count += 1;
- ignore = ignore->next;
- }
- }
-
- //count += prg->rtd->lelInfo[kid->tree->id].numCaptureAttr;
-
- if ( !( parseTree->flags & PF_NAMED ) &&
- !( parseTree->flags & PF_ARTIFICIAL ) &&
- tree_child( prg, kid->tree ) != 0 )
- {
- countNodes( prg, count, parseTree->child, tree_child( prg, kid->tree ) );
- }
- countNodes( prg, count, parseTree->next, kid->next );
- }
-}
-
-void fillNodes( program_t *prg, int &nextAvail, struct bindings *bindings, long &bindId,
- struct pat_cons_node *nodes, parse_tree_t *parseTree, kid_t *kid, int ind )
-{
- if ( kid != 0 ) {
- struct pat_cons_node &node = nodes[ind];
-
- kid_t *child =
- !( parseTree->flags & PF_NAMED ) &&
- !( parseTree->flags & PF_ARTIFICIAL ) &&
- tree_child( prg, kid->tree ) != 0
- ?
- tree_child( prg, kid->tree ) : 0;
-
- parse_tree_t *ptChild =
- !( parseTree->flags & PF_NAMED ) &&
- !( parseTree->flags & PF_ARTIFICIAL ) &&
- tree_child( prg, kid->tree ) != 0
- ?
- parseTree->child : 0;
-
- /* Set up the fields. */
- node.id = kid->tree->id;
- node.prod_num = kid->tree->prod_num;
- node.length = string_length( kid->tree->tokdata );
- node.data = string_data( kid->tree->tokdata );
-
- /* Ignore items. */
- tree_t *ignoreList = tree_left_ignore( prg, kid->tree );
- kid_t *ignore = ignoreList == 0 ? 0 : ignoreList->child;
- node.left_ignore = ignore == 0 ? -1 : nextAvail;
-
- while ( ignore != 0 ) {
- struct pat_cons_node &node = nodes[nextAvail++];
-
- memset( &node, 0, sizeof(struct pat_cons_node) );
- node.id = ignore->tree->id;
- node.prod_num = ignore->tree->prod_num;
- node.next = ignore->next == 0 ? -1 : nextAvail;
-
- node.length = string_length( ignore->tree->tokdata );
- node.data = string_data( ignore->tree->tokdata );
-
- ignore = ignore->next;
- }
-
- /* Ignore items. */
- ignoreList = tree_right_ignore( prg, kid->tree );
- ignore = ignoreList == 0 ? 0 : ignoreList->child;
- node.right_ignore = ignore == 0 ? -1 : nextAvail;
-
- while ( ignore != 0 ) {
- struct pat_cons_node &node = nodes[nextAvail++];
-
- memset( &node, 0, sizeof(struct pat_cons_node) );
- node.id = ignore->tree->id;
- node.prod_num = ignore->tree->prod_num;
- node.next = ignore->next == 0 ? -1 : nextAvail;
-
- node.length = string_length( ignore->tree->tokdata );
- node.data = string_data( ignore->tree->tokdata );
-
- ignore = ignore->next;
- }
-
- ///* The captured attributes. */
- //for ( int i = 0; i < prg->rtd->lelInfo[kid->tree->id].numCaptureAttr; i++ ) {
- // CaptureAttr *cap = prg->rtd->captureAttr +
- // prg->rtd->lelInfo[kid->tree->id].captureAttr + i;
- //
- // tree_t *attr = colm_get_attr( kid->tree, cap->offset );
- //
- // struct pat_cons_node &node = nodes[nextAvail++];
- // memset( &node, 0, sizeof(struct pat_cons_node) );
- //
- // node.id = attr->id;
- // node.prodNum = attr->prodNum;
- // node.length = stringLength( attr->tokdata );
- // node.data = stringData( attr->tokdata );
- //}
-
- node.stop = parseTree->flags & PF_TERM_DUP;
-
- node.child = child == 0 ? -1 : nextAvail++;
-
- /* Recurse. */
- fillNodes( prg, nextAvail, bindings, bindId, nodes, ptChild, child, node.child );
-
- /* Since the parser is bottom up the bindings are in a bottom up
- * traversal order. Check after recursing. */
- node.bind_id = 0;
- if ( bindId < bindings->length() && bindings->data[bindId] == parseTree ) {
- /* Remember that binding ids are indexed from one. */
- node.bind_id = bindId++;
-
- //cout << "binding match in " << __PRETTY_FUNCTION__ << endl;
- //cout << "bindId: " << node.bindId << endl;
- }
-
- node.next = kid->next == 0 ? -1 : nextAvail++;
-
- /* Move to the next child. */
- fillNodes( prg, nextAvail, bindings, bindId, nodes, parseTree->next, kid->next, node.next );
- }
-}
-
-void Compiler::fillInPatterns( program_t *prg )
-{
- /*
- * patReplNodes
- */
-
- /* Count is referenced and computed by mapNode. */
- int count = 0;
- for ( PatList::Iter pat = patternList; pat.lte(); pat++ ) {
- countNodes( prg, count,
- pat->pdaRun->stack_top->next,
- pat->pdaRun->stack_top->next->shadow );
- }
-
- for ( ConsList::Iter repl = replList; repl.lte(); repl++ ) {
- countNodes( prg, count,
- repl->pdaRun->stack_top->next,
- repl->pdaRun->stack_top->next->shadow );
- }
-
- runtimeData->pat_repl_nodes = new pat_cons_node[count];
- runtimeData->num_pattern_nodes = count;
-
- int nextAvail = 0;
-
- for ( PatList::Iter pat = patternList; pat.lte(); pat++ ) {
- int ind = nextAvail++;
- runtimeData->pat_repl_info[pat->patRepId].offset = ind;
-
- /* BindIds are indexed base one. */
- runtimeData->pat_repl_info[pat->patRepId].num_bindings =
- pat->pdaRun->bindings->length() - 1;
-
- /* Init the bind */
- long bindId = 1;
- fillNodes( prg, nextAvail, pat->pdaRun->bindings, bindId,
- runtimeData->pat_repl_nodes,
- pat->pdaRun->stack_top->next,
- pat->pdaRun->stack_top->next->shadow,
- ind );
- }
-
- for ( ConsList::Iter repl = replList; repl.lte(); repl++ ) {
- int ind = nextAvail++;
- runtimeData->pat_repl_info[repl->patRepId].offset = ind;
-
- /* BindIds are indexed base one. */
- runtimeData->pat_repl_info[repl->patRepId].num_bindings =
- repl->pdaRun->bindings->length() - 1;
-
- long bindId = 1;
- fillNodes( prg, nextAvail, repl->pdaRun->bindings, bindId,
- runtimeData->pat_repl_nodes,
- repl->pdaRun->stack_top->next,
- repl->pdaRun->stack_top->next->shadow,
- ind );
- }
-
- assert( nextAvail == count );
-}
-
-
-int Compiler::findIndexOff( struct pda_tables *pdaTables, PdaGraph *pdaGraph, PdaState *state, int &curLen )
-{
- for ( int start = 0; start < curLen; ) {
- int offset = start;
- for ( TransMap::Iter trans = state->transMap; trans.lte(); trans++ ) {
- if ( pdaTables->owners[offset] != -1 )
- goto next_start;
-
- offset++;
- if ( ! trans.last() ) {
- TransMap::Iter next = trans.next();
- offset += next->key - trans->key - 1;
- }
- }
-
- /* Got though the whole list without a conflict. */
- return start;
-
-next_start:
- start++;
- }
-
- return curLen;
-}
-
-struct CmpSpan
-{
- static int compare( PdaState *state1, PdaState *state2 )
- {
- int dist1 = 0, dist2 = 0;
-
- if ( state1->transMap.length() > 0 ) {
- TransMap::Iter first1 = state1->transMap.first();
- TransMap::Iter last1 = state1->transMap.last();
- dist1 = last1->key - first1->key;
- }
-
- if ( state2->transMap.length() > 0 ) {
- TransMap::Iter first2 = state2->transMap.first();
- TransMap::Iter last2 = state2->transMap.last();
- dist2 = last2->key - first2->key;
- }
-
- if ( dist1 < dist2 )
- return 1;
- else if ( dist2 < dist1 )
- return -1;
- return 0;
- }
-};
-
-PdaGraph *Compiler::makePdaGraph( LangElSet &parserEls )
-{
- //for ( DefList::Iter prod = prodList; prod.lte(); prod++ )
- // cerr << prod->prodId << " " << prod->data << endl;
-
- PdaGraph *pdaGraph = new PdaGraph();
- lalr1GenerateParser( pdaGraph, parserEls );
- pdaGraph->setStateNumbers();
- analyzeMachine( pdaGraph, parserEls );
-
- //cerr << "NUMBER OF STATES: " << pdaGraph->stateList.length() << endl;
-
- return pdaGraph;
-}
-
-struct pda_tables *Compiler::makePdaTables( PdaGraph *pdaGraph )
-{
- int count, pos;
- struct pda_tables *pdaTables = new pda_tables;
-
- /*
- * Counting max indices.
- */
- count = 0;
- for ( PdaStateList::Iter state = pdaGraph->stateList; state.lte(); state++ ) {
- for ( TransMap::Iter trans = state->transMap; trans.lte(); trans++ ) {
- count++;
- if ( ! trans.last() ) {
- TransMap::Iter next = trans.next();
- count += next->key - trans->key - 1;
- }
- }
- }
-
-
- /* Allocate indicies and owners. */
- pdaTables->num_indicies = count;
- pdaTables->indicies = new int[count];
- pdaTables->owners = new int[count];
- for ( long i = 0; i < count; i++ ) {
- pdaTables->indicies[i] = -1;
- pdaTables->owners[i] = -1;
- }
-
- /* Allocate offsets. */
- int numStates = pdaGraph->stateList.length();
- pdaTables->offsets = new unsigned int[numStates];
- pdaTables->num_states = numStates;
-
- /* Place transitions into indicies/owners */
- PdaState **states = new PdaState*[numStates];
- long ds = 0;
- for ( PdaStateList::Iter state = pdaGraph->stateList; state.lte(); state++ )
- states[ds++] = state;
-
- /* Sorting baseded on span length. Gives an improvement, but incures a
- * cost. Off for now. */
- //MergeSort< PdaState*, CmpSpan > mergeSort;
- //mergeSort.sort( states, numStates );
-
- int indLen = 0;
- for ( int s = 0; s < numStates; s++ ) {
- PdaState *state = states[s];
-
- int indOff = findIndexOff( pdaTables, pdaGraph, state, indLen );
- pdaTables->offsets[state->stateNum] = indOff;
-
- for ( TransMap::Iter trans = state->transMap; trans.lte(); trans++ ) {
- pdaTables->indicies[indOff] = trans->value->actionSetEl->key.id;
- pdaTables->owners[indOff] = state->stateNum;
- indOff++;
-
- if ( ! trans.last() ) {
- TransMap::Iter next = trans.next();
- indOff += next->key - trans->key - 1;
- }
- }
-
- if ( indOff > indLen )
- indLen = indOff;
- }
-
- /* We allocated the max, but cmpression gives us less. */
- pdaTables->num_indicies = indLen;
- delete[] states;
-
-
- /*
- * Keys
- */
- count = pdaGraph->stateList.length() * 2;;
- pdaTables->keys = new int[count];
- pdaTables->num_keys = count;
-
- count = 0;
- for ( PdaStateList::Iter state = pdaGraph->stateList; state.lte(); state++ ) {
- if ( state->transMap.length() == 0 ) {
- pdaTables->keys[count+0] = 0;
- pdaTables->keys[count+1] = 0;
- }
- else {
- TransMap::Iter first = state->transMap.first();
- TransMap::Iter last = state->transMap.last();
- pdaTables->keys[count+0] = first->key;
- pdaTables->keys[count+1] = last->key;
- }
- count += 2;
- }
-
- /*
- * Targs
- */
- count = pdaGraph->actionSet.length();
- pdaTables->targs = new unsigned int[count];
- pdaTables->num_targs = count;
-
- count = 0;
- for ( PdaActionSet::Iter asi = pdaGraph->actionSet; asi.lte(); asi++ )
- pdaTables->targs[count++] = asi->key.targ;
-
- /*
- * ActInds
- */
- count = pdaGraph->actionSet.length();
- pdaTables->act_inds = new unsigned int[count];
- pdaTables->num_act_inds = count;
-
- count = pos = 0;
- for ( PdaActionSet::Iter asi = pdaGraph->actionSet; asi.lte(); asi++ ) {
- pdaTables->act_inds[count++] = pos;
- pos += asi->key.actions.length() + 1;
- }
-
- /*
- * Actions
- */
- count = 0;
- for ( PdaActionSet::Iter asi = pdaGraph->actionSet; asi.lte(); asi++ )
- count += asi->key.actions.length() + 1;
-
- pdaTables->actions = new unsigned int[count];
- pdaTables->num_actions = count;
-
- count = 0;
- for ( PdaActionSet::Iter asi = pdaGraph->actionSet; asi.lte(); asi++ ) {
- for ( ActDataList::Iter ali = asi->key.actions; ali.lte(); ali++ )
- pdaTables->actions[count++] = *ali;
-
- pdaTables->actions[count++] = 0;
- }
-
- /*
- * CommitLen
- */
- count = pdaGraph->actionSet.length();
- pdaTables->commit_len = new int[count];
- pdaTables->num_commit_len = count;
-
- count = 0;
- for ( PdaActionSet::Iter asi = pdaGraph->actionSet; asi.lte(); asi++ )
- pdaTables->commit_len[count++] = asi->key.commitLen;
-
- /*
- * tokenRegionInds. Start at one so region index 0 is null (unset).
- */
- count = 0;
- pos = 1;
- pdaTables->token_region_inds = new int[pdaTables->num_states];
- for ( PdaStateList::Iter state = pdaGraph->stateList; state.lte(); state++ ) {
- pdaTables->token_region_inds[count++] = pos;
- pos += state->regions.length() + 1;
- }
-
-
- /*
- * tokenRegions. Build in a null at the beginning.
- */
-
- count = 1;
- for ( PdaStateList::Iter state = pdaGraph->stateList; state.lte(); state++ )
- count += state->regions.length() + 1;
-
- pdaTables->num_region_items = count;
- pdaTables->token_regions = new int[pdaTables->num_region_items];
-
- count = 0;
- pdaTables->token_regions[count++] = 0;
- for ( PdaStateList::Iter state = pdaGraph->stateList; state.lte(); state++ ) {
- for ( RegionVect::Iter reg = state->regions; reg.lte(); reg++ ) {
- int id = ( *reg == EOF_REGION ) ? 0 : (*reg)->id + 1;
- pdaTables->token_regions[count++] = id;
- }
-
- pdaTables->token_regions[count++] = 0;
- }
-
- /*
- * tokenPreRegions. Build in a null at the beginning.
- */
-
- count = 1;
- for ( PdaStateList::Iter state = pdaGraph->stateList; state.lte(); state++ )
- count += state->regions.length() + 1;
-
- pdaTables->num_pre_region_items = count;
- pdaTables->token_pre_regions = new int[pdaTables->num_pre_region_items];
-
- count = 0;
- pdaTables->token_pre_regions[count++] = 0;
- for ( PdaStateList::Iter state = pdaGraph->stateList; state.lte(); state++ ) {
- for ( RegionVect::Iter reg = state->regions; reg.lte(); reg++ ) {
- assert( state->preRegions.length() <= 1 );
- if ( state->preRegions.length() == 0 || state->preRegions[0]->impl->wasEmpty )
- pdaTables->token_pre_regions[count++] = -1;
- else
- pdaTables->token_pre_regions[count++] = state->preRegions[0]->id + 1;
- }
-
- pdaTables->token_pre_regions[count++] = 0;
- }
-
-
- return pdaTables;
-}
-
-void Compiler::makeParser( LangElSet &parserEls )
-{
- pdaGraph = makePdaGraph( parserEls );
- pdaTables = makePdaTables( pdaGraph );
-}
-