summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2012-05-20 16:10:31 -0400
committerAdrian Thurston <thurston@complang.org>2012-05-20 16:10:31 -0400
commit600af732eb8d0e655ad2a2a450e998106ffab0c6 (patch)
tree5656ded8301013a7f6a3da484ce881f350404146
parentb5bedab8125194f9c359c29ad50b51799d932a56 (diff)
downloadcolm-600af732eb8d0e655ad2a2a450e998106ffab0c6.tar.gz
first checkin on no-kid-flags and no-ignore-dupes branch
Trying out an elimination of the kid flags and the duplicate ignore tokens. The kid flags waste a lot of space. There is also a bug WRT iterators. Some kids in the ref chain are actually on the stack only the tree is safe to edit because the stack variables are not full kids. The duplicate ignores causes a complicated implementation in the print function. It may actually be unneeded now that we have follow ignores. We can also provide some control over where the ignore tokens go, to the right of the left token or to the left of the right token.
-rw-r--r--colm/bytecode.h5
-rw-r--r--colm/pdabuild.cc31
-rw-r--r--colm/pdacodegen.cc3
-rw-r--r--colm/pdarun.c92
-rw-r--r--colm/pdarun.h3
-rw-r--r--colm/tree.c209
-rw-r--r--colm/tree.h3
7 files changed, 215 insertions, 131 deletions
diff --git a/colm/bytecode.h b/colm/bytecode.h
index 27fe071a..4734b152 100644
--- a/colm/bytecode.h
+++ b/colm/bytecode.h
@@ -359,11 +359,6 @@ typedef unsigned char uchar;
#define AF_LEFT_IGNORE 0x0100
#define AF_RIGHT_IGNORE 0x0200
-#define KF_SUPPRESS_RIGHT 0x01
-#define KF_SUPPRESS_LEFT 0x02
-#define KF_SUPPRESS_ORIGHT 0x04
-#define KF_SUPPRESS_OLEFT 0x08
-
/*
* Call stack.
*/
diff --git a/colm/pdabuild.cc b/colm/pdabuild.cc
index e645395e..5e79415a 100644
--- a/colm/pdabuild.cc
+++ b/colm/pdabuild.cc
@@ -1571,6 +1571,7 @@ void countNodes( Program *prg, int &count, ParseTree *parseTree, Kid *kid )
if ( kid != 0 ) {
count += 1;
+ /* Should't have to recurse here. */
IgnoreList *ignoreList = treeLeftIgnore( prg, kid->tree );
if ( ignoreList != 0 ) {
Kid *ignore = ignoreList->child;
@@ -1579,6 +1580,15 @@ void countNodes( Program *prg, int &count, ParseTree *parseTree, Kid *kid )
ignore = ignore->next;
}
}
+
+ ignoreList = treeRightIgnore( prg, kid->tree );
+ if ( ignoreList != 0 ) {
+ Kid *ignore = ignoreList->child;
+ while ( ignore != 0 ) {
+ count += 1;
+ ignore = ignore->next;
+ }
+ }
//count += prg->rtd->lelInfo[kid->tree->id].numCaptureAttr;
@@ -1621,7 +1631,26 @@ void fillNodes( Program *prg, int &nextAvail, Bindings *bindings, long &bindId,
/* Ignore items. */
IgnoreList *ignoreList = treeLeftIgnore( prg, kid->tree );
Kid *ignore = ignoreList == 0 ? 0 : ignoreList->child;
- node.ignore = ignore == 0 ? -1 : nextAvail;
+ node.leftIgnore = ignore == 0 ? -1 : nextAvail;
+
+ while ( ignore != 0 ) {
+ PatReplNode &node = nodes[nextAvail++];
+
+ memset( &node, 0, sizeof(PatReplNode) );
+ node.id = ignore->tree->id;
+ node.prodNum = ignore->tree->prodNum;
+ node.next = ignore->next == 0 ? -1 : nextAvail;
+
+ node.length = stringLength( ignore->tree->tokdata );
+ node.data = stringData( ignore->tree->tokdata );
+
+ ignore = ignore->next;
+ }
+
+ /* Ignore items. */
+ ignoreList = treeRightIgnore( prg, kid->tree );
+ ignore = ignoreList == 0 ? 0 : ignoreList->child;
+ node.rightIgnore = ignore == 0 ? -1 : nextAvail;
while ( ignore != 0 ) {
PatReplNode &node = nodes[nextAvail++];
diff --git a/colm/pdacodegen.cc b/colm/pdacodegen.cc
index 226d3ef5..a259ce00 100644
--- a/colm/pdacodegen.cc
+++ b/colm/pdacodegen.cc
@@ -322,7 +322,8 @@ void PdaCodeGen::writeRuntimeData( RuntimeData *runtimeData, PdaTables *pdaTable
}
out << ", " << node.length << ", ";
- out << node.ignore << ", ";
+ out << node.leftIgnore << ", ";
+ out << node.rightIgnore << ", ";
out << (int)node.stop << " },\n";
}
diff --git a/colm/pdarun.c b/colm/pdarun.c
index b24e5583..2b500bbc 100644
--- a/colm/pdarun.c
+++ b/colm/pdarun.c
@@ -536,26 +536,42 @@ static void reportParseError( Program *prg, Tree **sp, PdaRun *pdaRun )
static void attachRightIgnore( Program *prg, Tree **sp, PdaRun *pdaRun, ParseTree *parseTree )
{
- if ( pdaRun->stackTop->id < prg->rtd->firstNonTermId ) {
+ if ( pdaRun->stackTop->id > 0 && pdaRun->stackTop->id < prg->rtd->firstNonTermId ) {
/* OK, do it */
+ debug( REALM_PARSE, "attaching right ignore\n" );
+
+ /* Reset. */
+ assert( ! ( parseTree->flags & PF_RIGHT_IL_ATTACHED ) );
+
+ ParseTree *accum = pdaRun->accumIgnore;
+ pdaRun->accumIgnore = 0;
/* The data list needs to be extracted and reversed. The parse tree list
* can remain in stack order. */
- ParseTree *child = pdaRun->accumIgnore;
+ ParseTree *child = accum, *last = 0;
Kid *dataChild = 0, *dataLast = 0;
while ( child ) {
dataChild = child->shadow;
+ ParseTree *next = child->next;
+
+ /* Reverse the lists. */
+ dataChild->next = dataLast;
+ child->next = last;
- Kid *kid = kidAllocate( prg );
- kid->tree = dataChild->tree;
- kid->next = dataLast;
- treeUpref( kid->tree );
+ /* Detach the parse tree from the data tree. */
+ child->shadow = 0;
- dataLast = kid;
- child = child->next;
+ /* Keep the last for reversal. */
+ dataLast = dataChild;
+ last = child;
+
+ child = next;
}
+ /* Last is now the first. */
+ parseTree->rightIgnore = last;
+
if ( dataChild != 0 ) {
debug( REALM_PARSE, "attaching ignore right\n" );
@@ -591,9 +607,6 @@ static void attachRightIgnore( Program *prg, Tree **sp, PdaRun *pdaRun, ParseTre
parseTree->flags |= PF_RIGHT_IL_ATTACHED;
}
- else {
- parseTree->shadow->flags |= KF_SUPPRESS_LEFT;
- }
}
}
@@ -629,10 +642,10 @@ static void attachLeftIgnore( Program *prg, Tree **sp, PdaRun *pdaRun, ParseTree
}
/* Last is now the first. */
- parseTree->ignore = last;
+ parseTree->leftIgnore = last;
if ( dataChild != 0 ) {
- debug( REALM_PARSE, "attaching ignore left\n" );
+ debug( REALM_PARSE, "attaching left ignore\n" );
Kid *ignoreKid = dataChild;
@@ -663,11 +676,6 @@ static void attachLeftIgnore( Program *prg, Tree **sp, PdaRun *pdaRun, ParseTree
parseTree->flags |= PF_LEFT_IL_ATTACHED;
}
- else {
- /* We need to do this only when it's possible that the token has come
- * in with an ignore list. */
- parseTree->shadow->flags |= KF_SUPPRESS_RIGHT;
- }
}
/* Not currently used. Need to revive this. WARNING: untested changes here */
@@ -675,11 +683,11 @@ static void detachRightIgnore( Program *prg, Tree **sp, PdaRun *pdaRun, ParseTre
{
/* Right ignore are immediately discarded since they are copies of
* left-ignores. */
+ Tree *rightIgnore = 0;
if ( parseTree->flags & PF_RIGHT_IL_ATTACHED ) {
/* Modifying the tree we are detaching from. */
parseTree->shadow->tree = splitTree( prg, parseTree->shadow->tree );
- Tree *rightIgnore = 0;
Kid *riKid = treeRightIgnoreKid( prg, parseTree->shadow->tree );
/* If the right ignore has a left ignore, then that was the original
@@ -699,8 +707,40 @@ static void detachRightIgnore( Program *prg, Tree **sp, PdaRun *pdaRun, ParseTre
}
parseTree->flags &= ~PF_RIGHT_IL_ATTACHED;
+ }
+
+ if ( parseTree->rightIgnore != 0 ) {
+ assert( rightIgnore != 0 );
- treeDownref( prg, sp, rightIgnore );
+ /* Transfer the trees to accumIgnore. */
+ ParseTree *ignore = parseTree->rightIgnore;
+ parseTree->rightIgnore = 0;
+
+ Kid *dataIgnore = rightIgnore->child;
+ rightIgnore->child = 0;
+
+ ParseTree *last = 0;
+ Kid *dataLast = 0;
+ while ( ignore != 0 ) {
+ ParseTree *next = ignore->next;
+ Kid *dataNext = dataIgnore->next;
+
+ /* Put the data trees underneath the parse trees. */
+ ignore->shadow = dataIgnore;
+
+ /* Reverse. */
+ ignore->next = last;
+ dataIgnore->next = dataLast;
+
+ /* Keep last for reversal. */
+ last = ignore;
+ dataLast = dataIgnore;
+
+ ignore = next;
+ dataIgnore = dataNext;
+ }
+
+ pdaRun->accumIgnore = last;
}
}
@@ -732,12 +772,12 @@ static void detachLeftIgnore( Program *prg, Tree **sp, PdaRun *pdaRun, FsmRun *f
}
}
- if ( parseTree->ignore != 0 ) {
+ if ( parseTree->leftIgnore != 0 ) {
assert( leftIgnore != 0 );
/* Transfer the trees to accumIgnore. */
- ParseTree *ignore = parseTree->ignore;
- parseTree->ignore = 0;
+ ParseTree *ignore = parseTree->leftIgnore;
+ parseTree->leftIgnore = 0;
Kid *dataIgnore = leftIgnore->child;
leftIgnore->child = 0;
@@ -1385,8 +1425,10 @@ void clearParseTree( Program *prg, Tree **sp, ParseTree *parseTree )
}
if ( pt->child != 0 )
clearParseTree( prg, sp, pt->child );
- if ( pt->ignore != 0 )
- clearParseTree( prg, sp, pt->ignore );
+ if ( pt->leftIgnore != 0 )
+ clearParseTree( prg, sp, pt->leftIgnore );
+ if ( pt->rightIgnore != 0 )
+ clearParseTree( prg, sp, pt->rightIgnore );
parseTreeFree( prg, pt );
pt = next;
}
diff --git a/colm/pdarun.h b/colm/pdarun.h
index 263f9deb..236f8793 100644
--- a/colm/pdarun.h
+++ b/colm/pdarun.h
@@ -150,7 +150,8 @@ typedef struct _PatReplNode
long bindId;
const char *data;
long length;
- long ignore;
+ long leftIgnore;
+ long rightIgnore;
/* Just match nonterminal, don't go inside. */
unsigned char stop;
diff --git a/colm/tree.c b/colm/tree.c
index ec24332c..fb9a9fbf 100644
--- a/colm/tree.c
+++ b/colm/tree.c
@@ -316,10 +316,40 @@ Tree *constructInput( Program *prg )
Kid *constructReplacementKid( Tree **bindings, Program *prg, Kid *prev, long pat );
-Kid *constructIgnoreList( Program *prg, long pat )
+static Kid *constructLeftIgnoreList( Program *prg, long pat )
{
PatReplNode *nodes = prg->rtd->patReplNodes;
- long ignore = nodes[pat].ignore;
+ long ignore = nodes[pat].leftIgnore;
+
+ Kid *first = 0, *last = 0;
+ while ( ignore >= 0 ) {
+ Head *ignoreData = stringAllocPointer( prg, nodes[ignore].data, nodes[ignore].length );
+
+ Tree *ignTree = treeAllocate( prg );
+ ignTree->refs = 1;
+ ignTree->id = nodes[ignore].id;
+ ignTree->tokdata = ignoreData;
+
+ Kid *ignKid = kidAllocate( prg );
+ ignKid->tree = ignTree;
+ ignKid->next = 0;
+
+ if ( last == 0 )
+ first = ignKid;
+ else
+ last->next = ignKid;
+
+ ignore = nodes[ignore].next;
+ last = ignKid;
+ }
+
+ return first;
+}
+
+static Kid *constructRightIgnoreList( Program *prg, long pat )
+{
+ PatReplNode *nodes = prg->rtd->patReplNodes;
+ long ignore = nodes[pat].rightIgnore;
Kid *first = 0, *last = 0;
while ( ignore >= 0 ) {
@@ -358,10 +388,10 @@ Tree *constructReplacementTree( Kid *kid, Tree **bindings, Program *prg, long pa
/* All bindings have been uprefed. */
tree = bindings[nodes[pat].bindId];
- long ignore = nodes[pat].ignore;
+ long ignore = nodes[pat].leftIgnore;
IgnoreList *leftIgnore = 0;
if ( ignore >= 0 ) {
- Kid *ignore = constructIgnoreList( prg, pat );
+ Kid *ignore = constructLeftIgnoreList( prg, pat );
tree = splitTree( prg, tree );
@@ -386,13 +416,35 @@ Tree *constructReplacementTree( Kid *kid, Tree **bindings, Program *prg, long pa
pushLeftIgnore( prg, tree, leftIgnore );
}
}
- else {
- if ( kid != 0 )
- kid->flags |= KF_SUPPRESS_RIGHT;
- }
- if ( kid != 0 )
- kid->flags |= KF_SUPPRESS_LEFT;
+ ignore = nodes[pat].rightIgnore;
+ IgnoreList *rightIgnore = 0;
+ if ( ignore >= 0 ) {
+ Kid *ignore = constructRightIgnoreList( prg, pat );
+
+ tree = splitTree( prg, tree );
+
+ rightIgnore = ilAllocate( prg );
+ rightIgnore->id = LEL_ID_IGNORE;
+ rightIgnore->child = ignore;
+ rightIgnore->generation = prg->nextIlGen++;
+
+ if ( tree->flags & AF_RIGHT_IGNORE ) {
+ /* The token already has a right-ignore. Merge by attaching it as a
+ * right ignore of the new list. */
+ Kid *curIgnore = treeRightIgnoreKid( prg, tree );
+ pushRightIgnore( prg, (Tree*)rightIgnore, (IgnoreList*)curIgnore->tree );
+
+ /* Replace the current ignore. */
+ curIgnore->tree->refs -= 1;
+ curIgnore->tree = (Tree*)rightIgnore;
+ treeUpref( (Tree*)rightIgnore );
+ }
+ else {
+ /* Attach the ignore list. */
+ pushRightIgnore( prg, tree, rightIgnore );
+ }
+ }
}
else {
tree = treeAllocate( prg );
@@ -405,11 +457,29 @@ Tree *constructReplacementTree( Kid *kid, Tree **bindings, Program *prg, long pa
int objectLength = lelInfo[tree->id].objectLength;
Kid *attrs = allocAttrs( prg, objectLength );
- Kid *ignore = constructIgnoreList( prg, pat );
Kid *child = constructReplacementKid( bindings, prg,
0, nodes[pat].child );
tree->child = kidListConcat( attrs, child );
+
+ /* Right first, then left. */
+ Kid *ignore = constructRightIgnoreList( prg, pat );
+ if ( ignore != 0 ) {
+ IgnoreList *ignoreList = ilAllocate( prg );
+ ignoreList->id = LEL_ID_IGNORE;
+ ignoreList->refs = 1;
+ ignoreList->child = ignore;
+ ignoreList->generation = prg->nextIlGen++;
+
+ Kid *ignoreHead = kidAllocate( prg );
+ ignoreHead->tree = (Tree*)ignoreList;
+ ignoreHead->next = tree->child;
+ tree->child = ignoreHead;
+
+ tree->flags |= AF_RIGHT_IGNORE;
+ }
+
+ ignore = constructLeftIgnoreList( prg, pat );
if ( ignore != 0 ) {
IgnoreList *ignoreList = ilAllocate( prg );
ignoreList->id = LEL_ID_IGNORE;
@@ -425,6 +495,7 @@ Tree *constructReplacementTree( Kid *kid, Tree **bindings, Program *prg, long pa
tree->flags |= AF_LEFT_IGNORE;
}
+
int i;
for ( i = 0; i < lelInfo[tree->id].numCaptureAttr; i++ ) {
long ci = pat+1+i;
@@ -1170,15 +1241,11 @@ Tree *getFieldSplit( Program *prg, Tree *tree, Word field )
void setUiterCur( Program *prg, UserIter *uiter, Tree *tree )
{
uiter->ref.kid->tree = tree;
- uiter->ref.kid->flags |= KF_SUPPRESS_RIGHT;
- uiter->ref.kid->flags |= KF_SUPPRESS_LEFT;
}
void setTriterCur( Program *prg, TreeIter *iter, Tree *tree )
{
iter->ref.kid->tree = tree;
- iter->ref.kid->flags |= KF_SUPPRESS_RIGHT;
- iter->ref.kid->flags |= KF_SUPPRESS_LEFT;
}
Tree *getPtrVal( Pointer *ptr )
@@ -1940,25 +2007,15 @@ enum ReturnType
Done = 1,
CollectIgnoreLeft,
CollectIgnoreRight,
- RecIgnoreList,
+// RecIgnoreList,
ChildPrint
};
-#define IPF_RIGHT_PRINTED 0x0001
-#define IPF_LEFT_PRESENT 0x0002
-#define IPF_TERM_PRINTED 0x0004
-#define IPF_SUPPRESS 0x0008
-
-/* Note that this function causes recursion, thought it is not a big
- * deal since the recursion it is only caused by nonterminals that are ignored. */
-
void printKid( Program *prg, Tree **sp, struct ColmPrintArgs *printArgs, Kid *kid )
{
enum ReturnType rt;
Kid *parent = 0;
- int printFlags = 0;
- Kid *leadingIgnore = 0;
- Kid *suppressLeftStop = 0;
+// Kid *leadingIgnore = 0;
/* Iterate the kids passed in. We are expecting a next, which will allow us
* to print the trailing ignore list. */
@@ -1972,21 +2029,6 @@ void printKid( Program *prg, Tree **sp, struct ColmPrintArgs *printArgs, Kid *ki
return;
rec_call:
- if ( kid->flags & KF_SUPPRESS_RIGHT )
- printFlags |= IPF_SUPPRESS;
-
- if ( kid->flags & KF_SUPPRESS_LEFT )
- suppressLeftStop = leadingIgnore;
-
- if ( kid->flags & KF_SUPPRESS_OLEFT ) {
- /* Free the leading ignore list. */
- while ( leadingIgnore != 0 ) {
- Kid *next = leadingIgnore->next;
- kidFree( prg, leadingIgnore );
- leadingIgnore = next;
- }
- }
-
if ( kid->tree == 0 )
goto skip_null;
@@ -2001,30 +2043,24 @@ rec_call:
kid = (Kid*)vm_pop();
}
+#if 0
/* If it is an ignore list, queue it and skip past the content. */
if ( kid->tree->id == LEL_ID_IGNORE ) {
- /* Ignore suppression can be triggered by a suppress right or suppress
- * outside left for example. */
- if ( ! (printFlags & IPF_SUPPRESS ) ) {
- debug( REALM_PRINT, "putting %p on ignore list\n", kid->tree );
- Kid *newIgnore = kidAllocate( prg );
- newIgnore->next = leadingIgnore;
- leadingIgnore = newIgnore;
- leadingIgnore->tree = kid->tree;
- }
+ debug( REALM_PRINT, "putting %p on ignore list\n", kid->tree );
+ Kid *newIgnore = kidAllocate( prg );
+ newIgnore->next = leadingIgnore;
+ leadingIgnore = newIgnore;
+ leadingIgnore->tree = kid->tree;
goto skip_node;
}
+#endif
- /* Terminals trigger leading ignore printing. */
- if ( kid->tree->id < prg->rtd->firstNonTermId ) {
- /* Reset suppress left stop. */
- suppressLeftStop = 0;
-
+#if 0
+ /* print leading ignore? Triggered by terminals. */
+ if ( kid->tree->id != LEL_ID_IGNORE && kid->tree->id < prg->rtd->firstNonTermId ) {
/* Reverse the leading ignore list. */
if ( leadingIgnore != 0 ) {
Kid *ignore = 0, *last = 0;
- long youngest = -1;
- Kid *youngestKid = 0;
debug( REALM_PRINT, "printing ignore %p\n", leadingIgnore->tree );
@@ -2033,11 +2069,6 @@ rec_call:
Kid *next = leadingIgnore->next;
leadingIgnore->next = last;
- if ( ((IgnoreList*)leadingIgnore->tree)->generation > youngest ) {
- youngest = ((IgnoreList*)leadingIgnore->tree)->generation;
- youngestKid = leadingIgnore;
- }
-
if ( next == 0 )
break;
@@ -2046,9 +2077,8 @@ rec_call:
}
/* Print the leading ignore list, free the kids in the process. */
- ignore = youngestKid;
- if ( printArgs->comm && ignore != 0 && kid->tree->id != 0 &&
- (printFlags & IPF_TERM_PRINTED) )
+ ignore = leadingIgnore;
+ if ( printArgs->comm && ignore != 0 && kid->tree->id != 0 )
{
/* Non-terminal. */
Kid *child = treeChild( prg, ignore->tree );
@@ -2079,19 +2109,16 @@ rec_call:
}
}
}
+#endif
/* Open the tree. */
printArgs->openTree( prg, sp, printArgs, parent, kid );
/* Print contents. */
- if ( kid->tree->id < prg->rtd->firstNonTermId ) {
+ if ( kid->tree->id != LEL_ID_IGNORE && kid->tree->id < prg->rtd->firstNonTermId ) {
debug( REALM_PRINT, "printing terminal %p\n", kid->tree );
- if ( kid->tree->id != 0 ) {
- printFlags |= IPF_TERM_PRINTED;
+ if ( kid->tree->id != 0 )
printArgs->printTerm( prg, sp, printArgs, kid );
- }
-
- printFlags &= ~IPF_SUPPRESS;
}
/* Print children. */
@@ -2117,36 +2144,23 @@ rec_call:
/* close the tree. */
printArgs->closeTree( prg, sp, printArgs, parent, kid );
-skip_node:
+//skip_node:
+
/* If not currently skipping ignore data, then print it. Ignore data can
* be associated with terminals and nonterminals. */
if ( kid->tree->flags & AF_RIGHT_IGNORE ) {
- if ( ! (printFlags & IPF_SUPPRESS ) ) {
- //emittedRightIgnore = true;
- vm_push( (SW)kid );
- kid = treeRightIgnoreKid( prg, kid->tree );
- vm_push( (SW) CollectIgnoreRight );
- goto rec_call;
- rec_return_ign_right:
- kid = (Kid*)vm_pop();
- }
+ debug( REALM_PRINT, "right ignore\n" );
+ vm_push( (SW)kid );
+ kid = treeRightIgnoreKid( prg, kid->tree );
+ vm_push( (SW) CollectIgnoreRight );
+ goto rec_call;
+ rec_return_ign_right:
+ kid = (Kid*)vm_pop();
}
/* For skiping over content on null. */
skip_null:
- if ( kid->flags & KF_SUPPRESS_LEFT ) {
- /* Free the leading ignore list. */
- while ( leadingIgnore != 0 && leadingIgnore != suppressLeftStop ) {
- Kid *next = leadingIgnore->next;
- kidFree( prg, leadingIgnore );
- leadingIgnore = next;
- }
- }
-
- if ( kid->flags & KF_SUPPRESS_ORIGHT )
- printFlags |= IPF_SUPPRESS;
-
rt = (enum ReturnType)vm_pop();
switch ( rt ) {
case Done:
@@ -2159,9 +2173,9 @@ skip_null:
case CollectIgnoreRight:
debug( REALM_PRINT, "return: ignore right\n" );
goto rec_return_ign_right;
- case RecIgnoreList:
- debug( REALM_PRINT, "return: ignore list\n" );
- goto rec_return_il;
+// case RecIgnoreList:
+// debug( REALM_PRINT, "return: ignore list\n" );
+// goto rec_return_il;
case ChildPrint:
debug( REALM_PRINT, "return: child print\n" );
goto rec_return;
@@ -2173,6 +2187,7 @@ void printTreeArgs( Program *prg, Tree **sp, struct ColmPrintArgs *printArgs, Tr
if ( tree == 0 )
printArgs->out( printArgs, "NIL", 3 );
else {
+ /* This term tree allows us to print trailing ignores. */
Tree termTree;
memset( &termTree, 0, sizeof(termTree) );
diff --git a/colm/tree.h b/colm/tree.h
index 9d6b0b21..e3fed750 100644
--- a/colm/tree.h
+++ b/colm/tree.h
@@ -110,7 +110,8 @@ typedef struct _ParseTree
struct _ParseTree *child;
struct _ParseTree *next;
- struct _ParseTree *ignore;
+ struct _ParseTree *leftIgnore;
+ struct _ParseTree *rightIgnore;
Kid *shadow;
/* Parsing algorithm. */