diff options
author | Adrian Thurston <thurston@complang.org> | 2012-05-21 11:56:31 -0400 |
---|---|---|
committer | Adrian Thurston <thurston@complang.org> | 2012-05-21 11:56:31 -0400 |
commit | 7487fbd6ff688e109a2d64aebaaf34cde28adde7 (patch) | |
tree | 988255e672383010210f38ba93bdb22f8b4be442 /colm | |
parent | 9d52a04592899e5f223e9b3fadec34458bb72b2a (diff) | |
download | colm-7487fbd6ff688e109a2d64aebaaf34cde28adde7.tar.gz |
clone removal
The ignore node handling code has been frequently cloned. Cleaning that up.
Diffstat (limited to 'colm')
-rw-r--r-- | colm/pdarun.c | 45 | ||||
-rw-r--r-- | colm/tree.c | 219 | ||||
-rw-r--r-- | colm/tree.h | 7 |
3 files changed, 141 insertions, 130 deletions
diff --git a/colm/pdarun.c b/colm/pdarun.c index 87efa92e..206d2df4 100644 --- a/colm/pdarun.c +++ b/colm/pdarun.c @@ -585,30 +585,19 @@ static void attachRightIgnore( Program *prg, Tree **sp, PdaRun *pdaRun, ParseTre rightIgnore->id = LEL_ID_IGNORE; rightIgnore->child = ignoreKid; - /* About to alter the data tree. Split first. */ - parseTree->shadow->tree = splitTree( prg, parseTree->shadow->tree ); - - if ( parseTree->shadow->tree->flags & AF_RIGHT_IGNORE ) { - /* The previous token already has a right ignore. Merge by - * attaching it as a left ignore of the new list. */ - Kid *curIgnore = treeRightIgnoreKid( prg, parseTree->shadow->tree ); - pushLeftIgnore( prg, rightIgnore, curIgnore->tree ); - - /* Replace the current ignore. */ - treeDownref( prg, sp, curIgnore->tree ); - curIgnore->tree = rightIgnore; - treeUpref( rightIgnore ); - } - else { - /* Attach The ignore list. */ - pushRightIgnore( prg, parseTree->shadow->tree, rightIgnore ); - } + Tree *pushTo = parseTree->shadow->tree; + + pushTo = pushRightIgnore2( prg, sp, pushTo, rightIgnore ); + + parseTree->shadow->tree = pushTo; parseTree->flags |= PF_RIGHT_IL_ATTACHED; } } } + + static void attachLeftIgnore( Program *prg, Tree **sp, PdaRun *pdaRun, ParseTree *parseTree ) { /* Reset. */ @@ -653,24 +642,12 @@ static void attachLeftIgnore( Program *prg, Tree **sp, PdaRun *pdaRun, ParseTree leftIgnore->id = LEL_ID_IGNORE; leftIgnore->child = ignoreKid; - parseTree->shadow->tree = splitTree( prg, parseTree->shadow->tree ); + Tree *pushTo = parseTree->shadow->tree; - /* Attach as left ignore to the token we are sending. */ - if ( parseTree->shadow->tree->flags & AF_LEFT_IGNORE ) { - /* The token already has a left-ignore. Merge by attaching it as a - * right ignore of the new list. */ - Kid *curIgnore = treeLeftIgnoreKid( prg, parseTree->shadow->tree ); - pushRightIgnore( prg, leftIgnore, curIgnore->tree ); + pushTo = pushLeftIgnore2( prg, sp, pushTo, leftIgnore ); + + parseTree->shadow->tree = pushTo; - /* Replace the current ignore. */ - treeDownref( prg, sp, curIgnore->tree ); - curIgnore->tree = leftIgnore; - treeUpref( leftIgnore ); - } - else { - /* Attach the ignore list. */ - pushLeftIgnore( prg, parseTree->shadow->tree, leftIgnore ); - } parseTree->flags |= PF_LEFT_IL_ATTACHED; } diff --git a/colm/tree.c b/colm/tree.c index b4916a9e..4e93be31 100644 --- a/colm/tree.c +++ b/colm/tree.c @@ -325,18 +325,17 @@ Tree *constructInput( Program *prg ) Kid *constructReplacementKid( Tree **bindings, Program *prg, Kid *prev, long pat ); -static Kid *constructLeftIgnoreList( Program *prg, long pat ) +static Kid *constructIgnoreList( Program *prg, long ignoreInd ) { PatReplNode *nodes = prg->rtd->patReplNodes; - long ignore = nodes[pat].leftIgnore; Kid *first = 0, *last = 0; - while ( ignore >= 0 ) { - Head *ignoreData = stringAllocPointer( prg, nodes[ignore].data, nodes[ignore].length ); + while ( ignoreInd >= 0 ) { + Head *ignoreData = stringAllocPointer( prg, nodes[ignoreInd].data, nodes[ignoreInd].length ); Tree *ignTree = treeAllocate( prg ); ignTree->refs = 1; - ignTree->id = nodes[ignore].id; + ignTree->id = nodes[ignoreInd].id; ignTree->tokdata = ignoreData; Kid *ignKid = kidAllocate( prg ); @@ -348,43 +347,145 @@ static Kid *constructLeftIgnoreList( Program *prg, long pat ) else last->next = ignKid; - ignore = nodes[ignore].next; + ignoreInd = nodes[ignoreInd].next; last = ignKid; } return first; } +static Kid *constructLeftIgnoreList( Program *prg, long pat ) +{ + PatReplNode *nodes = prg->rtd->patReplNodes; + return constructIgnoreList( prg, nodes[pat].leftIgnore ); +} + static Kid *constructRightIgnoreList( Program *prg, long pat ) { PatReplNode *nodes = prg->rtd->patReplNodes; - long ignore = nodes[pat].rightIgnore; + return constructIgnoreList( prg, nodes[pat].rightIgnore ); +} - Kid *first = 0, *last = 0; - while ( ignore >= 0 ) { - Head *ignoreData = stringAllocPointer( prg, nodes[ignore].data, nodes[ignore].length ); +static void pushLeftIgnore( Program *prg, Tree *tree, Tree *ignoreList ) +{ + assert( ! (tree->flags & AF_LEFT_IGNORE) ); - Tree *ignTree = treeAllocate( prg ); - ignTree->refs = 1; - ignTree->id = nodes[ignore].id; - ignTree->tokdata = ignoreData; + /* Allocate. */ + Kid *kid = kidAllocate( prg ); + kid->tree = ignoreList; + treeUpref( ignoreList ); - Kid *ignKid = kidAllocate( prg ); - ignKid->tree = ignTree; - ignKid->next = 0; + /* Attach it. */ + kid->next = tree->child; + tree->child = kid; - if ( last == 0 ) - first = ignKid; - else - last->next = ignKid; + tree->flags |= AF_LEFT_IGNORE; +} - ignore = nodes[ignore].next; - last = ignKid; +static void pushRightIgnore( Program *prg, Tree *tree, Tree *ignoreList ) +{ + assert( ! (tree->flags & AF_RIGHT_IGNORE) ); + + /* Insert an ignore head in the child list. */ + Kid *kid = kidAllocate( prg ); + kid->tree = (Tree*)ignoreList; + treeUpref( (Tree*)ignoreList ); + + /* Attach it. */ + if ( tree->flags & AF_LEFT_IGNORE ) { + kid->next = tree->child->next; + tree->child->next = kid; + } + else { + kid->next = tree->child; + tree->child = kid; } - return first; + tree->flags |= AF_RIGHT_IGNORE; +} + +Tree *pushRightIgnore2( Program *prg, Tree **sp, Tree *pushTo, Tree *rightIgnore ) +{ + /* About to alter the data tree. Split first. */ + pushTo = splitTree( prg, pushTo ); + + if ( pushTo->flags & AF_RIGHT_IGNORE ) { + /* The previous token already has a right ignore. Merge by + * attaching it as a left ignore of the new list. */ + Kid *curIgnore = treeRightIgnoreKid( prg, pushTo ); + pushLeftIgnore( prg, rightIgnore, curIgnore->tree ); + + /* Replace the current ignore. */ + treeDownref( prg, sp, curIgnore->tree ); + curIgnore->tree = rightIgnore; + treeUpref( rightIgnore ); + } + else { + /* Attach The ignore list. */ + pushRightIgnore( prg, pushTo, rightIgnore ); + } + + return pushTo; +} + +Tree *pushLeftIgnore2( Program *prg, Tree **sp, Tree *pushTo, Tree *leftIgnore ) +{ + pushTo = splitTree( prg, pushTo ); + + /* Attach as left ignore to the token we are sending. */ + if ( pushTo->flags & AF_LEFT_IGNORE ) { + /* The token already has a left-ignore. Merge by attaching it as a + * right ignore of the new list. */ + Kid *curIgnore = treeLeftIgnoreKid( prg, pushTo ); + pushRightIgnore( prg, leftIgnore, curIgnore->tree ); + + /* Replace the current ignore. */ + treeDownref( prg, sp, curIgnore->tree ); + curIgnore->tree = leftIgnore; + treeUpref( leftIgnore ); + } + else { + /* Attach the ignore list. */ + pushLeftIgnore( prg, pushTo, leftIgnore ); + } + + return pushTo; } + +void popLeftIgnore( Program *prg, Tree **sp, Tree *tree ) +{ + assert( tree->flags & AF_LEFT_IGNORE ); + + Kid *next = tree->child->next; + treeDownref( prg, sp, tree->child->tree ); + kidFree( prg, tree->child ); + tree->child = next; + + tree->flags &= ~AF_LEFT_IGNORE; +} + +void popRightIgnore( Program *prg, Tree **sp, Tree *tree ) +{ + assert( tree->flags & AF_RIGHT_IGNORE ); + + if ( tree->flags & AF_LEFT_IGNORE ) { + Kid *next = tree->child->next->next; + treeDownref( prg, sp, tree->child->next->tree ); + kidFree( prg, tree->child->next ); + tree->child->next = next; + } + else { + Kid *next = tree->child->next; + treeDownref( prg, sp, tree->child->tree ); + kidFree( prg, tree->child ); + tree->child = next; + } + + tree->flags &= ~AF_RIGHT_IGNORE; +} + + /* Returns an uprefed tree. Saves us having to downref and bindings to zero to * return a zero-ref tree. */ Tree *constructReplacementTree( Kid *kid, Tree **bindings, Program *prg, long pat ) @@ -1072,76 +1173,6 @@ Kid *treeAttr( Program *prg, const Tree *tree ) return kid; } -void pushLeftIgnore( Program *prg, Tree *tree, Tree *ignoreList ) -{ - assert( ! (tree->flags & AF_LEFT_IGNORE) ); - - /* Allocate. */ - Kid *kid = kidAllocate( prg ); - kid->tree = ignoreList; - treeUpref( ignoreList ); - - /* Attach it. */ - kid->next = tree->child; - tree->child = kid; - - tree->flags |= AF_LEFT_IGNORE; -} - -void pushRightIgnore( Program *prg, Tree *tree, Tree *ignoreList ) -{ - assert( ! (tree->flags & AF_RIGHT_IGNORE) ); - - /* Insert an ignore head in the child list. */ - Kid *kid = kidAllocate( prg ); - kid->tree = (Tree*)ignoreList; - treeUpref( (Tree*)ignoreList ); - - /* Attach it. */ - if ( tree->flags & AF_LEFT_IGNORE ) { - kid->next = tree->child->next; - tree->child->next = kid; - } - else { - kid->next = tree->child; - tree->child = kid; - } - - tree->flags |= AF_RIGHT_IGNORE; -} - -void popLeftIgnore( Program *prg, Tree **sp, Tree *tree ) -{ - assert( tree->flags & AF_LEFT_IGNORE ); - - Kid *next = tree->child->next; - treeDownref( prg, sp, tree->child->tree ); - kidFree( prg, tree->child ); - tree->child = next; - - tree->flags &= ~AF_LEFT_IGNORE; -} - -void popRightIgnore( Program *prg, Tree **sp, Tree *tree ) -{ - assert( tree->flags & AF_RIGHT_IGNORE ); - - if ( tree->flags & AF_LEFT_IGNORE ) { - Kid *next = tree->child->next->next; - treeDownref( prg, sp, tree->child->next->tree ); - kidFree( prg, tree->child->next ); - tree->child->next = next; - } - else { - Kid *next = tree->child->next; - treeDownref( prg, sp, tree->child->tree ); - kidFree( prg, tree->child ); - tree->child = next; - } - - tree->flags &= ~AF_RIGHT_IGNORE; -} - Tree *treeLeftIgnore( Program *prg, Tree *tree ) { if ( tree->flags & AF_LEFT_IGNORE ) diff --git a/colm/tree.h b/colm/tree.h index 8d100389..ced24a78 100644 --- a/colm/tree.h +++ b/colm/tree.h @@ -261,8 +261,11 @@ typedef struct _UserIter void treeUpref( Tree *tree ); void treeDownref( struct ColmProgram *prg, Tree **sp, Tree *tree ); long cmpTree( struct ColmProgram *prg, const Tree *tree1, const Tree *tree2 ); -void pushLeftIgnore( struct ColmProgram *prg, Tree *tree, Tree *ignoreList ); -void pushRightIgnore( struct ColmProgram *prg, Tree *tree, Tree *ignoreList ); + +Tree *pushRightIgnore2( struct ColmProgram *prg, Tree **sp, Tree *pushTo, Tree *rightIgnore ); +Tree *pushLeftIgnore2( struct ColmProgram *prg, Tree **sp, Tree *pushTo, Tree *leftIgnore ); +//void pushLeftIgnore( struct ColmProgram *prg, Tree *tree, Tree *ignoreList ); +//void pushRightIgnore( struct ColmProgram *prg, Tree *tree, Tree *ignoreList ); void popLeftIgnore( struct ColmProgram *prg, Tree **sp, Tree *tree ); void popRightIgnore( struct ColmProgram *prg, Tree **sp, Tree *tree ); Tree *treeLeftIgnore( struct ColmProgram *prg, Tree *tree ); |