[Redbutton-devel] SF.net SVN: redbutton: [341] redbutton-author/trunk/ccc.y
Brought to you by:
skilvington
|
From: <ski...@us...> - 2007-08-23 16:11:41
|
Revision: 341
http://redbutton.svn.sourceforge.net/redbutton/?rev=341&view=rev
Author: skilvington
Date: 2007-08-23 09:11:36 -0700 (Thu, 23 Aug 2007)
Log Message:
-----------
output yacc grammar for optional items
Modified Paths:
--------------
redbutton-author/trunk/ccc.y
Modified: redbutton-author/trunk/ccc.y
===================================================================
--- redbutton-author/trunk/ccc.y 2007-08-23 13:10:24 UTC (rev 340)
+++ redbutton-author/trunk/ccc.y 2007-08-23 16:11:36 UTC (rev 341)
@@ -3,6 +3,7 @@
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
+#include <ctype.h>
#define YYSTYPE char *
@@ -20,6 +21,7 @@
struct item *next;
char *name;
enum item_type type;
+ bool include; /* should we output this optional item or not */
};
/* the literal strings we need to make into %token's */
@@ -67,6 +69,8 @@
}
/* here we go ... */
+void output_item(struct item *, bool);
+
void print_tokens(struct token *);
char *add_token(struct token **, char *);
char *unquote(char *);
@@ -131,6 +135,7 @@
new_item->next = NULL;
new_item->name = name; /* lex strdup's it for us */
new_item->type = type;
+ new_item->include = true;
return;
}
@@ -140,58 +145,14 @@
{
struct item *item;
struct item *next;
- char *tok_name;
buf_append(&state.grammar, name);
buf_append(&state.grammar, ":\n\t");
+ /* output each item that makes up this identifier */
for(item=state.items; item; item=item->next)
- {
- switch(item->type)
- {
- case IT_LITERAL:
- tok_name = add_token(&state.tokens, item->name);
- buf_append(&state.grammar, tok_name);
- break;
+ output_item(item, true);
- case IT_IDENTIFIER:
- buf_append(&state.grammar, item->name);
- break;
-
- case IT_OPTIONAL:
-buf_append(&state.grammar, "[FIXME:");
-buf_append(&state.grammar, item->name);
-buf_append(&state.grammar, "]");
- break;
-
- case IT_ONEORMORE:
- /* add "OneOrMoreIdentifier" to the grammar */
- buf_append(&state.grammar, "OneOrMore");
- buf_append(&state.grammar, item->name);
- /* now create the OneOrMoreIdentifier rule */
- buf_append(&state.oneormores, "OneOrMore");
- buf_append(&state.oneormores, item->name);
- buf_append(&state.oneormores, ":\n\t");
- buf_append(&state.oneormores, item->name);
- buf_append(&state.oneormores, "\n\t|\n\t");
- buf_append(&state.oneormores, "OneOrMore");
- buf_append(&state.oneormores, item->name);
- buf_append(&state.oneormores, " ");
- buf_append(&state.oneormores, item->name);
- buf_append(&state.oneormores, "\n\t;\n\n");
- break;
-
- default:
- fatal("Unexpected item type");
- break;
- }
- /* do we need all the items, or just one of them */
- if(state.and_items)
- buf_append(&state.grammar, item->next ? " " : "\n\t");
- else
- buf_append(&state.grammar, item->next ? "\n\t|\n\t" : "\n\t");
- }
-
buf_append(&state.grammar, ";\n\n");
/* free the items */
@@ -209,6 +170,84 @@
}
void
+output_item(struct item *item, bool recurse)
+{
+ char *tok_name;
+ struct item *rest;
+
+ switch(item->type)
+ {
+ case IT_LITERAL:
+ tok_name = add_token(&state.tokens, item->name);
+ buf_append(&state.grammar, tok_name);
+ break;
+
+ case IT_IDENTIFIER:
+ buf_append(&state.grammar, item->name);
+ break;
+
+ case IT_OPTIONAL:
+ if(recurse)
+ {
+ /*
+ * we are an optional item,
+ * so first output the remaining items
+ * this creates a rule which does not including us
+ */
+ item->include = false;
+ for(rest=item->next; rest; rest=rest->next)
+ output_item(rest, true);
+ /* or it with a rule which does contain us */
+ if(item->next == NULL)
+ buf_append(&state.grammar, "\n\t");
+ buf_append(&state.grammar, "|\n\t");
+ /*
+ * now output the items before us and output ourself,
+ * this constructs a rule including us
+ */
+ item->include = true;
+ for(rest=state.items; rest!=item; rest=rest->next)
+ output_item(rest, false);
+ buf_append(&state.grammar, item->name);
+ }
+ else if(item->include)
+ {
+ buf_append(&state.grammar, item->name);
+ }
+ break;
+
+ case IT_ONEORMORE:
+ /* add "OneOrMoreIdentifier" to the grammar */
+ buf_append(&state.grammar, "OneOrMore");
+ buf_append(&state.grammar, item->name);
+ /* now create the OneOrMoreIdentifier rule */
+ buf_append(&state.oneormores, "OneOrMore");
+ buf_append(&state.oneormores, item->name);
+ buf_append(&state.oneormores, ":\n\t");
+ buf_append(&state.oneormores, item->name);
+ buf_append(&state.oneormores, "\n\t|\n\t");
+ buf_append(&state.oneormores, "OneOrMore");
+ buf_append(&state.oneormores, item->name);
+ buf_append(&state.oneormores, " ");
+ buf_append(&state.oneormores, item->name);
+ buf_append(&state.oneormores, "\n\t;\n\n");
+ break;
+
+ default:
+ fatal("Unexpected item type");
+ break;
+ }
+
+ /* do we need all the items, or just one of them */
+ if(state.and_items)
+ buf_append(&state.grammar, item->next ? (item->include ? " " : "") : "\n\t");
+ else
+ buf_append(&state.grammar, item->next ? "\n\t|\n\t" : "\n\t");
+
+ return;
+}
+
+void
print_tokens(struct token *t)
{
while(t)
@@ -370,6 +409,7 @@
%%
clauses:
+ /* empty */
|
clauses clause
;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|