diff options
author | Adrian Thurston <thurston@complang.org> | 2011-09-27 16:19:52 +0000 |
---|---|---|
committer | Adrian Thurston <thurston@complang.org> | 2011-09-27 16:19:52 +0000 |
commit | 0f5e9459e0b19d3fc9c2ea486949003e08501f66 (patch) | |
tree | 466b83bf45d5651a830dc2b65cae0c90eda7eb29 | |
parent | 345e6310ff259895de57d3544875c830cc57f738 (diff) | |
download | colm-0f5e9459e0b19d3fc9c2ea486949003e08501f66.tar.gz |
Now printing rights only if there are no lefts. Also simplifed the ignore
printing: separate passes for printing and clearning. refs #323.
-rw-r--r-- | colm/tree.c | 80 |
1 files changed, 52 insertions, 28 deletions
diff --git a/colm/tree.c b/colm/tree.c index 912fdc9e..e11f88b7 100644 --- a/colm/tree.c +++ b/colm/tree.c @@ -2005,6 +2005,9 @@ enum ReturnType ChildPrint }; +#define IPF_RIGHT_PRINTED 0x0001 +#define IPF_LEFT_PRESENT 0x0001 + /* 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. */ @@ -2052,44 +2055,65 @@ rec_call: /* Reverse the leading ignore list. */ if ( leadingIgnore != 0 ) { - long rightPrinted = 0; + long printFlags = 0; + Kid *ignore = 0, *last = 0; + debug( REALM_PRINT, "printing ignore %p\n", leadingIgnore->tree ); + leadingIgnore = reverseKidList( leadingIgnore ); - /* Print the leading ignore list, free the kids in the process. */ - while ( leadingIgnore != 0 ) { - if ( leadingIgnore->tree->flags & AF_IS_LEFT_IGNORE && rightPrinted > 0 ) + /* Reverse the list. */ + while ( true ) { + Kid *next = leadingIgnore->next; + leadingIgnore->next = last; + + if ( leadingIgnore->tree->flags & AF_IS_LEFT_IGNORE ) + printFlags |= IPF_LEFT_PRESENT; + + if ( next == 0 ) break; + + last = leadingIgnore; + leadingIgnore = next; + } + + /* Print the leading ignore list, free the kids in the process. */ + ignore = leadingIgnore; + while ( ignore != 0 ) { + if ( (ignore->tree->flags & AF_IS_RIGHT_IGNORE) && (printFlags & IPF_LEFT_PRESENT) ) + { + debug( RELAM_PRINT, "skipping right ignore because left is present\n" ); + /* Skip. */ + } + else { - /* Non-terminal. */ - Kid *child = treeChild( prg, leadingIgnore->tree ); - if ( child != 0 ) { - vm_push( (SW)rightPrinted ); - vm_push( (SW)leadingIgnore ); - vm_push( (SW)kid ); - leadingIgnore = 0; - kid = child; - while ( kid != 0 ) { - debug( REALM_PRINT, "rec call on %p\n", kid->tree ); - vm_push( (SW) IgnoreList ); - goto rec_call; - rec_return_il: - kid = kid->next; + /* Non-terminal. */ + Kid *child = treeChild( prg, ignore->tree ); + if ( child != 0 ) { + vm_push( (SW)leadingIgnore ); + vm_push( (SW)printFlags ); + vm_push( (SW)ignore ); + vm_push( (SW)kid ); + leadingIgnore = 0; + kid = child; + while ( kid != 0 ) { + debug( REALM_PRINT, "rec call on %p\n", kid->tree ); + vm_push( (SW) IgnoreList ); + goto rec_call; + rec_return_il: + kid = kid->next; + } + kid = (Kid*)vm_pop(); + ignore = (Kid*)vm_pop(); + printFlags = (long)vm_pop(); + leadingIgnore = (Kid*)vm_pop(); } - kid = (Kid*)vm_pop(); - leadingIgnore = (Kid*)vm_pop(); - rightPrinted = (long)vm_pop(); } - if ( leadingIgnore->tree->flags & AF_IS_RIGHT_IGNORE ) - rightPrinted += 1; - - Kid *next = leadingIgnore->next; - kidFree( prg, leadingIgnore ); - leadingIgnore = next; + ignore = ignore->next; } - /* Consume anything left over after stopping. */ + /* Free the leading ignore list. */ while ( leadingIgnore != 0 ) { Kid *next = leadingIgnore->next; kidFree( prg, leadingIgnore ); |