[Redbutton-devel] SF.net SVN: redbutton: [335] redbutton-author/trunk/ccc.y
Brought to you by:
skilvington
|
From: <ski...@us...> - 2007-08-23 10:03:28
|
Revision: 335
http://redbutton.svn.sourceforge.net/redbutton/?rev=335&view=rev
Author: skilvington
Date: 2007-08-23 03:03:26 -0700 (Thu, 23 Aug 2007)
Log Message:
-----------
output %token directives for the literal strings
Modified Paths:
--------------
redbutton-author/trunk/ccc.y
Modified: redbutton-author/trunk/ccc.y
===================================================================
--- redbutton-author/trunk/ccc.y 2007-08-23 08:43:41 UTC (rev 334)
+++ redbutton-author/trunk/ccc.y 2007-08-23 10:03:26 UTC (rev 335)
@@ -22,16 +22,35 @@
enum item_type type;
};
+/* the literal strings we need to make into %token's */
+struct token
+{
+ struct token *next;
+ char *name;
+};
+
+/* build up the separate parts of the ouput file in these buffers */
+struct buf
+{
+ char *str; /* the buffer */
+ size_t len; /* length of the string in the buffer */
+ size_t nalloced; /* number of bytes malloc'ed to the buffer */
+};
+
/* global state */
struct
{
struct item *items; /* NULL => start a new identifier */
bool and_items; /* true => identifier must contain all items */
+ struct token *tokens; /* "%token" section of the output file */
+ struct buf grammar; /* grammar section of the output file */
+ struct buf oneormores; /* grammar section for Identifier+ rules */
} state;
/* input line we are currently parsing */
int yylineno = 1;
+/* yacc functions we need to provide */
void
yyerror(const char *str)
{
@@ -46,13 +65,30 @@
return 1;
}
+/* here we go ... */
+void print_tokens(struct token *);
+void add_token(struct token **, char *);
+char *unquote(char *);
+
+void buf_init(struct buf *);
+void buf_append(struct buf *, char *);
+
int
main(void)
{
state.items = NULL;
+ state.tokens = NULL;
+ buf_init(&state.grammar);
+ buf_init(&state.oneormores);
yyparse();
+ print_tokens(state.tokens);
+ printf("%%%%\n");
+ printf("%s", state.grammar.str);
+ printf("%s", state.oneormores.str);
+ printf("%%%%\n");
+
return EXIT_SUCCESS;
}
@@ -99,16 +135,34 @@
struct item *item;
struct item *next;
-printf("%s:\n", name);
-for(item=state.items; item; item=item->next)
-{
-printf("\t%s",item->name);
-if(item->type==IT_OPTIONAL) printf(" [optional]");
-if(item->type==IT_ONEORMORE) printf(" oneormore+");
-if(item->next && !state.and_items) printf (" |");
-printf("\n");
-}
+ buf_append(&state.grammar, name);
+ buf_append(&state.grammar, ":\n");
+ for(item=state.items; item; item=item->next)
+ {
+ switch(item->type)
+ {
+ case IT_LITERAL:
+ add_token(&state.tokens, item->name);
+ break;
+
+ case IT_IDENTIFIER:
+ break;
+
+ case IT_OPTIONAL:
+ break;
+
+ case IT_ONEORMORE:
+ break;
+
+ default:
+ fatal("Unexpected item type");
+ break;
+ }
+ }
+
+ buf_append(&state.grammar, "\t;\n\n");
+
/* free the items */
item = state.items;
while(item)
@@ -123,6 +177,147 @@
return;
}
+void
+print_tokens(struct token *t)
+{
+ while(t)
+ {
+ printf("%%token %s\n", t->name);
+ t = t->next;
+ }
+
+ return;
+}
+
+void
+add_token(struct token **head, char *quoted)
+{
+ struct token *t = malloc(sizeof(struct token));
+ struct token *list;
+
+ if(t == NULL)
+ fatal("Out of memory");
+
+ t->next = NULL;
+ t->name = unquote(quoted);
+
+ /* check we haven't got it already */
+ list = *head;
+ while(list)
+ {
+ if(strcmp(list->name, t->name) == 0)
+ {
+ free(t->name);
+ free(t);
+ return;
+ }
+ list = list->next;
+ }
+
+ /* add it to the end of the list */
+ if(*head == NULL)
+ {
+ *head = t;
+ }
+ else
+ {
+ list = *head;
+ while(list->next)
+ list = list->next;
+ list->next = t;
+ }
+
+ return;
+}
+
+char *
+unquote(char *q)
+{
+ char *output;
+ char *unq;
+
+ /* check for special cases */
+ if(strcmp(q, "\"}\"") == 0)
+ {
+ if((output = strdup("RBRACE")) == NULL)
+ fatal("Out of memory");
+ return output;
+ }
+ else if(strcmp(q, "\"(\"") == 0)
+ {
+ if((output = strdup("LPAREN")) == NULL)
+ fatal("Out of memory");
+ return output;
+ }
+ else if(strcmp(q, "\")\"") == 0)
+ {
+ if((output = strdup("RPAREN")) == NULL)
+ fatal("Out of memory");
+ return output;
+ }
+
+ /* max length it could be */
+ if((output = malloc(strlen(q) + 1)) == NULL)
+ fatal("Out of memory");
+
+ /*
+ * remove any non-alphabetic chars (inc the start and end ")
+ * convert the remaining chars to uppercase
+ */
+ unq = output;
+ while(*q)
+ {
+ if(isalpha(*q))
+ {
+ *unq = toupper(*q);
+ unq ++;
+ }
+ q ++;
+ }
+
+ /* terminate it */
+ *unq = '\0';
+
+ /* sanity check */
+ if(output[0] == '\0')
+ fatal("Invalid literal string");
+
+ return output;
+}
+
+#define INIT_BUF_SIZE 1024
+
+void
+buf_init(struct buf *b)
+{
+ b->len = 0;
+ b->nalloced = INIT_BUF_SIZE;
+ if((b->str = malloc(b->nalloced)) == NULL)
+ fatal("Out of memory");
+
+ return;
+}
+
+void
+buf_append(struct buf *b, char *app_str)
+{
+ size_t app_len = strlen(app_str);
+
+ /* +1 for the \0 terminator */
+ while(b->nalloced < b->len + app_len + 1)
+ {
+ b->nalloced *= 2;
+ if((b->str = realloc(b->str, b->nalloced)) == NULL)
+ fatal("Out of memory");
+ }
+
+ memcpy(b->str + b->len, app_str, app_len);
+ b->len += app_len;
+ b->str[b->len] = '\0';
+
+ return;
+}
+
%}
%token COMMENT
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|