Thread: [Redbutton-devel] SF.net SVN: redbutton: [330] redbutton-author/trunk/ccc.y
Brought to you by:
skilvington
|
From: <ski...@us...> - 2007-08-22 13:32:08
|
Revision: 330
http://redbutton.svn.sourceforge.net/redbutton/?rev=330&view=rev
Author: skilvington
Date: 2007-08-22 06:32:05 -0700 (Wed, 22 Aug 2007)
Log Message:
-----------
where to set and/or flag
Modified Paths:
--------------
redbutton-author/trunk/ccc.y
Modified: redbutton-author/trunk/ccc.y
===================================================================
--- redbutton-author/trunk/ccc.y 2007-08-22 13:26:22 UTC (rev 329)
+++ redbutton-author/trunk/ccc.y 2007-08-22 13:32:05 UTC (rev 330)
@@ -54,8 +54,14 @@
definition:
and_items
+ {
+ printf("AND-");
+ }
|
or_items
+ {
+ printf("OR-");
+ }
;
and_items:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-08-22 16:23:46
|
Revision: 332
http://redbutton.svn.sourceforge.net/redbutton/?rev=332&view=rev
Author: skilvington
Date: 2007-08-22 09:23:44 -0700 (Wed, 22 Aug 2007)
Log Message:
-----------
read the input file into a data structure
Modified Paths:
--------------
redbutton-author/trunk/ccc.y
Modified: redbutton-author/trunk/ccc.y
===================================================================
--- redbutton-author/trunk/ccc.y 2007-08-22 15:32:46 UTC (rev 331)
+++ redbutton-author/trunk/ccc.y 2007-08-22 16:23:44 UTC (rev 332)
@@ -1,9 +1,34 @@
%{
#include <stdio.h>
#include <string.h>
+#include <stdbool.h>
+#include <stdlib.h>
#define YYSTYPE char *
+/* build up a list of items that define the current identifier */
+enum item_type
+{
+ IT_LITERAL, /* "LiteralString" */
+ IT_IDENTIFIER, /* NormalIdentifier */
+ IT_OPTIONAL, /* [OptionalIdentifier] */
+ IT_ONEORMORE /* OneOrMoreIdentifier+ */
+};
+
+struct item
+{
+ struct item *next;
+ char *name;
+ enum item_type type;
+};
+
+/* global state */
+struct
+{
+ struct item *items; /* NULL => start a new identifier */
+ bool and_items; /* true => identifier must contain all items */
+} state;
+
/* input line we are currently parsing */
int yylineno = 1;
@@ -11,6 +36,8 @@
yyerror(const char *str)
{
fprintf(stderr, "Error: %s at line %d\n", str, yylineno);
+
+ return;
}
int
@@ -22,11 +49,83 @@
int
main(void)
{
+ state.items = NULL;
+
yyparse();
- return 0;
+ return EXIT_SUCCESS;
}
+void
+fatal(char *str)
+{
+ yyerror(str);
+
+ exit(EXIT_FAILURE);
+}
+
+void
+add_item(enum item_type type, char *name)
+{
+ struct item *new_item;
+
+ if(name == NULL)
+ fatal("Out of memory");
+
+ if(state.items == NULL)
+ {
+ if((state.items = malloc(sizeof(struct item))) == NULL)
+ fatal("Out of memory");
+ new_item = state.items;
+ }
+ else
+ {
+ /* find the end of the list */
+ struct item *i = state.items;
+ while(i->next)
+ i = i->next;
+ if((i->next = malloc(sizeof(struct item))) == NULL)
+ fatal("Out of memory");
+ new_item = i->next;
+ }
+
+ new_item->next = NULL;
+ new_item->name = name; /* lex strdup's it for us */
+ new_item->type = type;
+
+ return;
+}
+
+void
+output_def(char *name)
+{
+ 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");
+}
+
+ /* free the items */
+ item = state.items;
+ while(item)
+ {
+ next = item->next;
+ free(item->name);
+ free(item);
+ item = next;
+ }
+ state.items = NULL;
+
+ return;
+}
+
%}
%token COMMENT
@@ -51,19 +150,19 @@
|
IDENTIFIER DEFINEDAS definition ENDCLAUSE
{
- printf("DEFINE:'%s'\n", $1);
+ output_def($1);
}
;
definition:
and_items
{
- printf("AND-");
+ state.and_items = true;
}
|
or_items
{
- printf("OR-");
+ state.and_items = false;
}
;
@@ -82,22 +181,22 @@
item:
LITERAL
{
- printf("LITERAL:'%s'\n", $1);
+ add_item(IT_LITERAL, $1);
}
|
IDENTIFIER
{
- printf("IDENTIFIER:'%s'\n", $1);
+ add_item(IT_IDENTIFIER, $1);
}
|
LBRACKET IDENTIFIER RBRACKET
{
- printf("[IDENTIFIER]:'%s'\n", $2);
+ add_item(IT_OPTIONAL, $2);
}
|
IDENTIFIER ONEORMORE
{
- printf("IDENTIFIER+:'%s'\n", $1);
+ add_item(IT_ONEORMORE, $1);
}
;
%%
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-08-22 16:30:21
|
Revision: 333
http://redbutton.svn.sourceforge.net/redbutton/?rev=333&view=rev
Author: skilvington
Date: 2007-08-22 09:30:14 -0700 (Wed, 22 Aug 2007)
Log Message:
-----------
factor out the malloc
Modified Paths:
--------------
redbutton-author/trunk/ccc.y
Modified: redbutton-author/trunk/ccc.y
===================================================================
--- redbutton-author/trunk/ccc.y 2007-08-22 16:23:44 UTC (rev 332)
+++ redbutton-author/trunk/ccc.y 2007-08-22 16:30:14 UTC (rev 333)
@@ -67,16 +67,15 @@
void
add_item(enum item_type type, char *name)
{
- struct item *new_item;
+ struct item *new_item = malloc(sizeof(struct item));
- if(name == NULL)
+ /* did our malloc or lex's strdup fail */
+ if(new_item == NULL || name == NULL)
fatal("Out of memory");
if(state.items == NULL)
{
- if((state.items = malloc(sizeof(struct item))) == NULL)
- fatal("Out of memory");
- new_item = state.items;
+ state.items = new_item;
}
else
{
@@ -84,9 +83,7 @@
struct item *i = state.items;
while(i->next)
i = i->next;
- if((i->next = malloc(sizeof(struct item))) == NULL)
- fatal("Out of memory");
- new_item = i->next;
+ i->next = new_item;
}
new_item->next = NULL;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
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.
|
|
From: <ski...@us...> - 2007-08-23 11:18:31
|
Revision: 337
http://redbutton.svn.sourceforge.net/redbutton/?rev=337&view=rev
Author: skilvington
Date: 2007-08-23 04:18:29 -0700 (Thu, 23 Aug 2007)
Log Message:
-----------
literal items may be alternates too
Modified Paths:
--------------
redbutton-author/trunk/ccc.y
Modified: redbutton-author/trunk/ccc.y
===================================================================
--- redbutton-author/trunk/ccc.y 2007-08-23 11:12:14 UTC (rev 336)
+++ redbutton-author/trunk/ccc.y 2007-08-23 11:18:29 UTC (rev 337)
@@ -146,33 +146,22 @@
case IT_LITERAL:
tok_name = add_token(&state.tokens, item->name);
buf_append(&state.grammar, tok_name);
- buf_append(&state.grammar, item->next ? " " : "\n\t");
break;
case IT_IDENTIFIER:
buf_append(&state.grammar, item->name);
- /* 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");
break;
case IT_OPTIONAL:
buf_append(&state.grammar, "[FIXME:");
buf_append(&state.grammar, item->name);
-buf_append(&state.grammar, "] ");
+buf_append(&state.grammar, "]");
break;
case IT_ONEORMORE:
/* add "IdentifierOneOrMore" to the grammar */
buf_append(&state.grammar, item->name);
buf_append(&state.grammar, "OneOrMore");
- /* 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");
/* now create the IdentifierOneOrMore rule */
buf_append(&state.oneormores, item->name);
buf_append(&state.oneormores, "OneOrMore:\n\t");
@@ -188,6 +177,11 @@
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");
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-08-23 11:27:30
|
Revision: 338
http://redbutton.svn.sourceforge.net/redbutton/?rev=338&view=rev
Author: skilvington
Date: 2007-08-23 04:27:23 -0700 (Thu, 23 Aug 2007)
Log Message:
-----------
generate lex output too
Modified Paths:
--------------
redbutton-author/trunk/ccc.y
Modified: redbutton-author/trunk/ccc.y
===================================================================
--- redbutton-author/trunk/ccc.y 2007-08-23 11:18:29 UTC (rev 337)
+++ redbutton-author/trunk/ccc.y 2007-08-23 11:27:23 UTC (rev 338)
@@ -42,8 +42,9 @@
{
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 lexer; /* lex output file */
+ struct token *tokens; /* "%token" section of the yacc output file */
+ struct buf grammar; /* grammar section of the yacc output file */
struct buf oneormores; /* grammar section for Identifier+ rules */
} state;
@@ -77,12 +78,17 @@
main(void)
{
state.items = NULL;
+ buf_init(&state.lexer);
state.tokens = NULL;
buf_init(&state.grammar);
buf_init(&state.oneormores);
yyparse();
+ printf("-- lex --\n");
+ printf("%s", state.lexer.str);
+
+ printf("-- yacc --\n");
print_tokens(state.tokens);
printf("%%%%\n");
printf("%s", state.grammar.str);
@@ -250,6 +256,12 @@
list->next = t;
}
+ /* add it to the lex output file */
+ buf_append(&state.lexer, quoted);
+ buf_append(&state.lexer, "\treturn ");
+ buf_append(&state.lexer, t->name);
+ buf_append(&state.lexer, ";\n");
+
return t->name;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-08-23 11:53:33
|
Revision: 336
http://redbutton.svn.sourceforge.net/redbutton/?rev=336&view=rev
Author: skilvington
Date: 2007-08-23 04:12:14 -0700 (Thu, 23 Aug 2007)
Log Message:
-----------
output the yacc grammar for everthing expect [optional] items
Modified Paths:
--------------
redbutton-author/trunk/ccc.y
Modified: redbutton-author/trunk/ccc.y
===================================================================
--- redbutton-author/trunk/ccc.y 2007-08-23 10:03:26 UTC (rev 335)
+++ redbutton-author/trunk/ccc.y 2007-08-23 11:12:14 UTC (rev 336)
@@ -29,7 +29,7 @@
char *name;
};
-/* build up the separate parts of the ouput file in these buffers */
+/* build up the separate parts of the output file in these buffers */
struct buf
{
char *str; /* the buffer */
@@ -67,7 +67,7 @@
/* here we go ... */
void print_tokens(struct token *);
-void add_token(struct token **, char *);
+char *add_token(struct token **, char *);
char *unquote(char *);
void buf_init(struct buf *);
@@ -134,25 +134,54 @@
{
struct item *item;
struct item *next;
+ char *tok_name;
buf_append(&state.grammar, name);
- buf_append(&state.grammar, ":\n");
+ buf_append(&state.grammar, ":\n\t");
for(item=state.items; item; item=item->next)
{
switch(item->type)
{
case IT_LITERAL:
- add_token(&state.tokens, item->name);
+ tok_name = add_token(&state.tokens, item->name);
+ buf_append(&state.grammar, tok_name);
+ buf_append(&state.grammar, item->next ? " " : "\n\t");
break;
case IT_IDENTIFIER:
+ buf_append(&state.grammar, item->name);
+ /* 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");
break;
case IT_OPTIONAL:
+buf_append(&state.grammar, "[FIXME:");
+buf_append(&state.grammar, item->name);
+buf_append(&state.grammar, "] ");
break;
case IT_ONEORMORE:
+ /* add "IdentifierOneOrMore" to the grammar */
+ buf_append(&state.grammar, item->name);
+ buf_append(&state.grammar, "OneOrMore");
+ /* 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");
+ /* now create the IdentifierOneOrMore rule */
+ buf_append(&state.oneormores, item->name);
+ buf_append(&state.oneormores, "OneOrMore:\n\t");
+ buf_append(&state.oneormores, item->name);
+ buf_append(&state.oneormores, "\n\t|\n\t");
+ buf_append(&state.oneormores, item->name);
+ buf_append(&state.oneormores, "OneOrMore ");
+ buf_append(&state.oneormores, item->name);
+ buf_append(&state.oneormores, "\n\t;\n\n");
break;
default:
@@ -161,7 +190,7 @@
}
}
- buf_append(&state.grammar, "\t;\n\n");
+ buf_append(&state.grammar, ";\n\n");
/* free the items */
item = state.items;
@@ -189,7 +218,7 @@
return;
}
-void
+char *
add_token(struct token **head, char *quoted)
{
struct token *t = malloc(sizeof(struct token));
@@ -209,7 +238,7 @@
{
free(t->name);
free(t);
- return;
+ return list->name;
}
list = list->next;
}
@@ -227,7 +256,7 @@
list->next = t;
}
- return;
+ return t->name;
}
char *
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-08-23 12:53:41
|
Revision: 339
http://redbutton.svn.sourceforge.net/redbutton/?rev=339&view=rev
Author: skilvington
Date: 2007-08-23 05:53:39 -0700 (Thu, 23 Aug 2007)
Log Message:
-----------
create OneOrMoreIdentifier rather than IdentifierOneOrMore
Modified Paths:
--------------
redbutton-author/trunk/ccc.y
Modified: redbutton-author/trunk/ccc.y
===================================================================
--- redbutton-author/trunk/ccc.y 2007-08-23 11:27:23 UTC (rev 338)
+++ redbutton-author/trunk/ccc.y 2007-08-23 12:53:39 UTC (rev 339)
@@ -165,16 +165,18 @@
break;
case IT_ONEORMORE:
- /* add "IdentifierOneOrMore" to the grammar */
+ /* add "OneOrMoreIdentifier" to the grammar */
+ buf_append(&state.grammar, "OneOrMore");
buf_append(&state.grammar, item->name);
- buf_append(&state.grammar, "OneOrMore");
- /* now create the IdentifierOneOrMore rule */
+ /* now create the OneOrMoreIdentifier rule */
+ buf_append(&state.oneormores, "OneOrMore");
buf_append(&state.oneormores, item->name);
- buf_append(&state.oneormores, "OneOrMore:\n\t");
+ 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, "OneOrMore ");
+ buf_append(&state.oneormores, " ");
buf_append(&state.oneormores, item->name);
buf_append(&state.oneormores, "\n\t;\n\n");
break;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
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.
|
|
From: <ski...@us...> - 2007-08-23 18:49:48
|
Revision: 342
http://redbutton.svn.sourceforge.net/redbutton/?rev=342&view=rev
Author: skilvington
Date: 2007-08-23 11:49:46 -0700 (Thu, 23 Aug 2007)
Log Message:
-----------
put the C code in the right place
Modified Paths:
--------------
redbutton-author/trunk/ccc.y
Modified: redbutton-author/trunk/ccc.y
===================================================================
--- redbutton-author/trunk/ccc.y 2007-08-23 16:11:36 UTC (rev 341)
+++ redbutton-author/trunk/ccc.y 2007-08-23 18:49:46 UTC (rev 342)
@@ -50,6 +50,18 @@
struct buf oneormores; /* grammar section for Identifier+ rules */
} state;
+void add_item(enum item_type, char *);
+
+void output_def(char *);
+void output_item(struct item *, bool);
+
+void print_tokens(struct token *);
+char *add_token(struct token **, char *);
+char *unquote(char *);
+
+void buf_init(struct buf *);
+void buf_append(struct buf *, char *);
+
/* input line we are currently parsing */
int yylineno = 1;
@@ -68,16 +80,83 @@
return 1;
}
-/* here we go ... */
-void output_item(struct item *, bool);
+%}
-void print_tokens(struct token *);
-char *add_token(struct token **, char *);
-char *unquote(char *);
+%token COMMENT
+%token LITERAL
+%token IDENTIFIER
+%token DEFINEDAS
+%token ALTERNATIVE
+%token LBRACKET
+%token RBRACKET
+%token ONEORMORE
+%token ENDCLAUSE
+%token INVALID
-void buf_init(struct buf *);
-void buf_append(struct buf *, char *);
+%%
+clauses:
+ /* empty */
+ |
+ clauses clause
+ ;
+clause:
+ COMMENT
+ |
+ IDENTIFIER DEFINEDAS definition ENDCLAUSE
+ {
+ output_def($1);
+ }
+ ;
+
+definition:
+ and_items
+ {
+ state.and_items = true;
+ }
+ |
+ or_items
+ {
+ state.and_items = false;
+ }
+ ;
+
+and_items:
+ item
+ |
+ and_items item
+ ;
+
+or_items:
+ item ALTERNATIVE item
+ |
+ or_items ALTERNATIVE item
+ ;
+
+item:
+ LITERAL
+ {
+ add_item(IT_LITERAL, $1);
+ }
+ |
+ IDENTIFIER
+ {
+ add_item(IT_IDENTIFIER, $1);
+ }
+ |
+ LBRACKET IDENTIFIER RBRACKET
+ {
+ add_item(IT_OPTIONAL, $2);
+ }
+ |
+ IDENTIFIER ONEORMORE
+ {
+ add_item(IT_ONEORMORE, $1);
+ }
+ ;
+%%
+
+/* here we go ... */
int
main(void)
{
@@ -394,78 +473,3 @@
return;
}
-%}
-
-%token COMMENT
-%token LITERAL
-%token IDENTIFIER
-%token DEFINEDAS
-%token ALTERNATIVE
-%token LBRACKET
-%token RBRACKET
-%token ONEORMORE
-%token ENDCLAUSE
-%token INVALID
-
-%%
-clauses:
- /* empty */
- |
- clauses clause
- ;
-
-clause:
- COMMENT
- |
- IDENTIFIER DEFINEDAS definition ENDCLAUSE
- {
- output_def($1);
- }
- ;
-
-definition:
- and_items
- {
- state.and_items = true;
- }
- |
- or_items
- {
- state.and_items = false;
- }
- ;
-
-and_items:
- item
- |
- and_items item
- ;
-
-or_items:
- item ALTERNATIVE item
- |
- or_items ALTERNATIVE item
- ;
-
-item:
- LITERAL
- {
- add_item(IT_LITERAL, $1);
- }
- |
- IDENTIFIER
- {
- add_item(IT_IDENTIFIER, $1);
- }
- |
- LBRACKET IDENTIFIER RBRACKET
- {
- add_item(IT_OPTIONAL, $2);
- }
- |
- IDENTIFIER ONEORMORE
- {
- add_item(IT_ONEORMORE, $1);
- }
- ;
-%%
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-08-24 08:56:57
|
Revision: 344
http://redbutton.svn.sourceforge.net/redbutton/?rev=344&view=rev
Author: skilvington
Date: 2007-08-24 01:56:51 -0700 (Fri, 24 Aug 2007)
Log Message:
-----------
add -l flag to select lexer or grammar output
Modified Paths:
--------------
redbutton-author/trunk/ccc.y
Modified: redbutton-author/trunk/ccc.y
===================================================================
--- redbutton-author/trunk/ccc.y 2007-08-23 18:50:46 UTC (rev 343)
+++ redbutton-author/trunk/ccc.y 2007-08-24 08:56:51 UTC (rev 344)
@@ -1,4 +1,5 @@
%{
+#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
@@ -50,6 +51,9 @@
struct buf oneormores; /* grammar section for Identifier+ rules */
} state;
+void usage(char *);
+void fatal(char *);
+
void add_item(enum item_type, char *);
void output_def(char *);
@@ -158,8 +162,28 @@
/* here we go ... */
int
-main(void)
+main(int argc, char *argv[])
{
+ char *prog_name = argv[0];
+ /* by default output the grammar */
+ bool show_lexer = false;
+ int arg;
+
+ while((arg = getopt(argc, argv, "l")) != EOF)
+ {
+ switch(arg)
+ {
+ case 'l':
+ show_lexer = true;
+ break;
+
+ default:
+ usage(prog_name);
+ break;
+ }
+ }
+
+ if(optind == argc)
state.items = NULL;
buf_init(&state.lexer);
state.tokens = NULL;
@@ -168,20 +192,33 @@
yyparse();
- printf("-- lex --\n");
- printf("%s", state.lexer.str);
+ if(show_lexer)
+ {
+ /* output lexer */
+ printf("%s", state.lexer.str);
+ }
+ else
+ {
+ /* output grammar */
+ print_tokens(state.tokens);
+ printf("%%%%\n");
+ printf("%s", state.grammar.str);
+ printf("%s", state.oneormores.str);
+ printf("%%%%\n");
+ }
- printf("-- yacc --\n");
- print_tokens(state.tokens);
- printf("%%%%\n");
- printf("%s", state.grammar.str);
- printf("%s", state.oneormores.str);
- printf("%%%%\n");
-
return EXIT_SUCCESS;
}
void
+usage(char *prog_name)
+{
+ fprintf(stderr, "Syntax: %s [-l]\n", prog_name);
+
+ exit(EXIT_FAILURE);
+}
+
+void
fatal(char *str)
{
yyerror(str);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-08-24 13:58:05
|
Revision: 348
http://redbutton.svn.sourceforge.net/redbutton/?rev=348&view=rev
Author: skilvington
Date: 2007-08-24 06:58:03 -0700 (Fri, 24 Aug 2007)
Log Message:
-----------
don't output multiple copies of OneOrMoreIdentifiers
Modified Paths:
--------------
redbutton-author/trunk/ccc.y
Modified: redbutton-author/trunk/ccc.y
===================================================================
--- redbutton-author/trunk/ccc.y 2007-08-24 13:36:03 UTC (rev 347)
+++ redbutton-author/trunk/ccc.y 2007-08-24 13:58:03 UTC (rev 348)
@@ -25,10 +25,10 @@
bool include; /* should we output this optional item or not */
};
-/* the literal strings we need to make into %token's */
-struct token
+/* a list of strings */
+struct str_list
{
- struct token *next;
+ struct str_list *next;
char *name;
};
@@ -43,12 +43,12 @@
/* global state */
struct
{
- struct item *items; /* NULL => start a new identifier */
- bool and_items; /* true => identifier must contain all items */
- struct buf lexer; /* lex output file */
- struct token *tokens; /* "%token" section of the yacc output file */
- struct buf grammar; /* grammar section of the yacc output file */
- struct buf oneormores; /* grammar section for Identifier+ rules */
+ struct item *items; /* NULL => start a new identifier */
+ bool and_items; /* true => identifier must contain all items */
+ struct buf lexer; /* lex output file */
+ struct str_list *tokens; /* "%token" section of the yacc output file */
+ struct buf grammar; /* grammar section of the yacc output file */
+ struct str_list *oneormores; /* grammar section for Identifier+ rules */
} state;
int yyparse(void);
@@ -62,10 +62,13 @@
void output_def(char *);
void output_item(struct item *, bool);
-void print_tokens(struct token *);
-char *add_token(struct token **, char *);
+void print_tokens(struct str_list *);
+char *add_token(struct str_list **, char *);
char *unquote(char *);
+void print_oneormores(struct str_list *);
+void add_oneormore(struct str_list **, char *);
+
void buf_init(struct buf *);
void buf_append(struct buf *, char *);
@@ -191,7 +194,7 @@
buf_init(&state.lexer);
state.tokens = NULL;
buf_init(&state.grammar);
- buf_init(&state.oneormores);
+ state.oneormores = NULL;
yyparse();
@@ -206,7 +209,7 @@
print_tokens(state.tokens);
printf("%%%%\n");
printf("%s", state.grammar.str);
- printf("%s", state.oneormores.str);
+ print_oneormores(state.oneormores);
printf("%%%%\n");
}
@@ -339,17 +342,8 @@
/* 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");
+ /* add the OneOrMoreIdentifier to our list */
+ add_oneormore(&state.oneormores, item->name);
break;
default:
@@ -367,7 +361,7 @@
}
void
-print_tokens(struct token *t)
+print_tokens(struct str_list *t)
{
while(t)
{
@@ -379,10 +373,10 @@
}
char *
-add_token(struct token **head, char *quoted)
+add_token(struct str_list **head, char *quoted)
{
- struct token *t = malloc(sizeof(struct token));
- struct token *list;
+ struct str_list *t = malloc(sizeof(struct str_list));
+ struct str_list *list;
if(t == NULL)
fatal("Out of memory");
@@ -480,6 +474,47 @@
return output;
}
+void
+print_oneormores(struct str_list *list)
+{
+ while(list)
+ {
+ /* output the OneOrMoreIdentifier rule */
+ printf("OneOrMore%s:\n", list->name);
+ printf("\t%s\n", list->name);
+ printf("\t|\n");
+ printf("\tOneOrMore%s %s\n", list->name, list->name);
+ printf("\t;\n\n");
+ list = list->next;
+ }
+
+ return;
+}
+
+void
+add_oneormore(struct str_list **head, char *name)
+{
+ struct str_list *list;
+
+ /* check we haven't got it already */
+ for(list=*head; list; list=list->next)
+ {
+ if(strcmp(list->name, name) == 0)
+ return;
+ }
+
+ /* take a copy of the string */
+ if((list = malloc(sizeof(struct str_list))) == NULL
+ || (list->name = strdup(name)) == NULL)
+ fatal("Out of memory");
+
+ /* add it to the head of the list */
+ list->next = *head;
+ *head = list;
+
+ return;
+}
+
#define INIT_BUF_SIZE 1024
void
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-08-24 16:07:42
|
Revision: 351
http://redbutton.svn.sourceforge.net/redbutton/?rev=351&view=rev
Author: skilvington
Date: 2007-08-24 09:07:40 -0700 (Fri, 24 Aug 2007)
Log Message:
-----------
check we have the right number of cmd line params
Modified Paths:
--------------
redbutton-author/trunk/ccc.y
Modified: redbutton-author/trunk/ccc.y
===================================================================
--- redbutton-author/trunk/ccc.y 2007-08-24 14:10:56 UTC (rev 350)
+++ redbutton-author/trunk/ccc.y 2007-08-24 16:07:40 UTC (rev 351)
@@ -189,7 +189,9 @@
}
}
- if(optind == argc)
+ if(optind != argc)
+ usage(prog_name);
+
state.items = NULL;
buf_init(&state.lexer);
state.tokens = NULL;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-08-26 11:09:42
|
Revision: 352
http://redbutton.svn.sourceforge.net/redbutton/?rev=352&view=rev
Author: skilvington
Date: 2007-08-26 03:10:07 -0700 (Sun, 26 Aug 2007)
Log Message:
-----------
allow format strings in buf_append
Modified Paths:
--------------
redbutton-author/trunk/ccc.y
Modified: redbutton-author/trunk/ccc.y
===================================================================
--- redbutton-author/trunk/ccc.y 2007-08-24 16:07:40 UTC (rev 351)
+++ redbutton-author/trunk/ccc.y 2007-08-26 10:10:07 UTC (rev 352)
@@ -1,9 +1,11 @@
%{
+#define _GNU_SOURCE /* for vasprintf */
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
+#include <stdarg.h>
#include <ctype.h>
#define YYSTYPE char *
@@ -70,7 +72,7 @@
void add_oneormore(struct str_list **, char *);
void buf_init(struct buf *);
-void buf_append(struct buf *, char *);
+void buf_append(struct buf *, char *, ...);
/* input line we are currently parsing */
int yylineno = 1;
@@ -270,8 +272,7 @@
struct item *item;
struct item *next;
- buf_append(&state.grammar, name);
- buf_append(&state.grammar, ":\n\t");
+ buf_append(&state.grammar, "%s:\n\t", name);
/* output each item that makes up this identifier */
for(item=state.items; item; item=item->next)
@@ -342,8 +343,7 @@
case IT_ONEORMORE:
/* add "OneOrMoreIdentifier" to the grammar */
- buf_append(&state.grammar, "OneOrMore");
- buf_append(&state.grammar, item->name);
+ buf_append(&state.grammar, "OneOrMore%s", item->name);
/* add the OneOrMoreIdentifier to our list */
add_oneormore(&state.oneormores, item->name);
break;
@@ -413,10 +413,7 @@
}
/* add it to the lex output file */
- buf_append(&state.lexer, quoted);
- buf_append(&state.lexer, "\treturn ");
- buf_append(&state.lexer, t->name);
- buf_append(&state.lexer, ";\n");
+ buf_append(&state.lexer, "%s\treturn %s;\n", quoted, t->name);
return t->name;
}
@@ -531,10 +528,17 @@
}
void
-buf_append(struct buf *b, char *app_str)
+buf_append(struct buf *b, char *fmt, ...)
{
- size_t app_len = strlen(app_str);
+ va_list ap;
+ char *app_str;
+ size_t app_len;
+ va_start(ap, fmt);
+ if((app_len = vasprintf(&app_str, fmt, ap)) < 0)
+ fatal("Out of memory or illegal format string");
+ va_end(ap);
+
/* +1 for the \0 terminator */
while(b->nalloced < b->len + app_len + 1)
{
@@ -547,6 +551,8 @@
b->len += app_len;
b->str[b->len] = '\0';
+ free(app_str);
+
return;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-08-28 20:37:51
|
Revision: 355
http://redbutton.svn.sourceforge.net/redbutton/?rev=355&view=rev
Author: skilvington
Date: 2007-08-28 13:37:47 -0700 (Tue, 28 Aug 2007)
Log Message:
-----------
generate SET parser functions
Modified Paths:
--------------
redbutton-author/trunk/ccc.y
Modified: redbutton-author/trunk/ccc.y
===================================================================
--- redbutton-author/trunk/ccc.y 2007-08-28 16:15:53 UTC (rev 354)
+++ redbutton-author/trunk/ccc.y 2007-08-28 20:37:47 UTC (rev 355)
@@ -395,7 +395,8 @@
case ASN1TYPE_SET:
/* assert */
if(!state.and_items)
- fatal("SET type, but and_items not set");
+ fatal("SET but and_items not set");
+ buf_append(&state.parser, "\ttoken_t next;\n\n");
item = state.items;
while(item && item->type == IT_LITERAL)
{
@@ -403,13 +404,34 @@
item = item->next;
}
buf_append(&state.parser, "\t/* SET */\n");
-buf_append(&state.parser, "// TODO: SET\n");
+ buf_append(&state.parser, "\twhile(true)\n\t{\n");
+ buf_append(&state.parser, "\t\tnext = next_token();\n");
+ while(item && item->type != IT_LITERAL)
+ {
+ if(item->type != IT_IDENTIFIER && item->type != IT_OPTIONAL)
+ fatal("SET but not Identifier or Optional");
+ buf_append(&state.parser, "\t\t/* %s */\n", item->name);
+ buf_append(&state.parser, "\t\tif(is_%s(next))\n\t\t{\n", item->name);
+ buf_append(&state.parser, "\t\t\tparse_%s(state);\n", item->name);
+ buf_append(&state.parser, "\t\t\tcontinue;\n\t\t}\n");
+ item = item->next;
+ }
+ /* didn't match any items, must be the end of the SET */
+ buf_append(&state.parser, "\t\telse\n\t\t{\n");
+ buf_append(&state.parser, "\t\t\tbreak;\n\t\t}\n");
+ buf_append(&state.parser, "\t}\n");
+ /* eat any trailing literals */
+ while(item && item->type == IT_LITERAL)
+ {
+buf_append(&state.parser, "\n// TODO: eat %s\n", item->name);
+ item = item->next;
+ }
break;
case ASN1TYPE_SEQUENCE:
/* assert */
if(!state.and_items)
- fatal("SEQUENCE type, but and_items not set");
+ fatal("SEQUENCE but and_items not set");
buf_append(&state.parser, "\t/* SEQUENCE */\n");
buf_append(&state.parser, "\ttoken_t next;\n");
item = state.items;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-08-28 20:42:03
|
Revision: 356
http://redbutton.svn.sourceforge.net/redbutton/?rev=356&view=rev
Author: skilvington
Date: 2007-08-28 13:41:58 -0700 (Tue, 28 Aug 2007)
Log Message:
-----------
get ready to generate the is_Xxx() functions
Modified Paths:
--------------
redbutton-author/trunk/ccc.y
Modified: redbutton-author/trunk/ccc.y
===================================================================
--- redbutton-author/trunk/ccc.y 2007-08-28 20:37:47 UTC (rev 355)
+++ redbutton-author/trunk/ccc.y 2007-08-28 20:41:58 UTC (rev 356)
@@ -53,7 +53,8 @@
struct str_list *tokens; /* "%token" section of the yacc output file */
struct buf grammar; /* grammar section of the yacc output file */
struct str_list *oneormores; /* grammar section for Identifier+ rules */
- struct buf parser; /* C code for the parser */
+ struct buf parse_fns; /* parse_Xxx() C functions for the parser */
+ struct buf is_fns; /* is_Xxx() C functions for the parser */
} state;
int yyparse(void);
@@ -206,7 +207,8 @@
state.tokens = NULL;
buf_init(&state.grammar);
state.oneormores = NULL;
- buf_init(&state.parser);
+ buf_init(&state.parse_fns);
+ buf_init(&state.is_fns);
yyparse();
@@ -218,7 +220,8 @@
else if(show_parser)
{
/* output C code */
- printf("%s", state.parser.str);
+ printf("%s", state.parse_fns.str);
+ printf("%s", state.is_fns.str);
}
else
{
@@ -295,7 +298,7 @@
buf_append(&state.grammar, ";\n\n");
/* C code for the parser */
- buf_append(&state.parser, "void parse_%s(struct state *state)\n{\n", name);
+ buf_append(&state.parse_fns, "void parse_%s(struct state *state)\n{\n", name);
/* count how many items make it up */
nitems = 0;
/* skip literals at the start */
@@ -313,33 +316,33 @@
item = state.items;
while(item && item->type == IT_LITERAL)
{
-buf_append(&state.parser, "// TODO: eat %s\n\n", item->name);
+buf_append(&state.parse_fns, "// TODO: eat %s\n\n", item->name);
item = item->next;
}
- buf_append(&state.parser, "\ttoken_t next = next_token();\n\n");
+ buf_append(&state.parse_fns, "\ttoken_t next = next_token();\n\n");
if(item->type == IT_IDENTIFIER)
{
- buf_append(&state.parser, "\t/* %s */\n", item->name);
- buf_append(&state.parser, "\tif(is_%s(next))\n", item->name);
- buf_append(&state.parser, "\t\tparse_%s(state);\n", item->name);
- buf_append(&state.parser, "\telse\n");
- buf_append(&state.parser, "\t\tparse_error(\"Expecting %s\");\n", item->name);
+ buf_append(&state.parse_fns, "\t/* %s */\n", item->name);
+ buf_append(&state.parse_fns, "\tif(is_%s(next))\n", item->name);
+ buf_append(&state.parse_fns, "\t\tparse_%s(state);\n", item->name);
+ buf_append(&state.parse_fns, "\telse\n");
+ buf_append(&state.parse_fns, "\t\tparse_error(\"Expecting %s\");\n", item->name);
}
else if(item->type == IT_OPTIONAL)
{
- buf_append(&state.parser, "\t/* [%s] */\n", item->name);
- buf_append(&state.parser, "\tif(is_%s(next))\n", item->name);
- buf_append(&state.parser, "\t\tparse_%s(state);\n", item->name);
+ buf_append(&state.parse_fns, "\t/* [%s] */\n", item->name);
+ buf_append(&state.parse_fns, "\tif(is_%s(next))\n", item->name);
+ buf_append(&state.parse_fns, "\t\tparse_%s(state);\n", item->name);
}
else if(item->type == IT_ONEORMORE)
{
- buf_append(&state.parser, "\t/* %s+ */\n", item->name);
- buf_append(&state.parser, "\twhile(is_%s(next))\n", item->name);
- buf_append(&state.parser, "\t{\n");
- buf_append(&state.parser, "\t\tparse_%s(state);\n", item->name);
- buf_append(&state.parser, "\t\tnext = next_token();\n");
- buf_append(&state.parser, "\t}\n");
- buf_append(&state.parser, "\n\tunget_token(next);\n");
+ buf_append(&state.parse_fns, "\t/* %s+ */\n", item->name);
+ buf_append(&state.parse_fns, "\twhile(is_%s(next))\n", item->name);
+ buf_append(&state.parse_fns, "\t{\n");
+ buf_append(&state.parse_fns, "\t\tparse_%s(state);\n", item->name);
+ buf_append(&state.parse_fns, "\t\tnext = next_token();\n");
+ buf_append(&state.parse_fns, "\t}\n");
+ buf_append(&state.parse_fns, "\n\tunget_token(next);\n");
}
else
{
@@ -348,7 +351,7 @@
item = item->next;
while(item)
{
-buf_append(&state.parser, "\n// TODO: eat %s\n", item->name);
+buf_append(&state.parse_fns, "\n// TODO: eat %s\n", item->name);
item = item->next;
}
}
@@ -361,26 +364,26 @@
/* assert */
if(state.and_items)
fatal("CHOICE or ENUMERATED type, but and_items set");
- buf_append(&state.parser, "\ttoken_t next = next_token();\n\n");
- buf_append(&state.parser, "\t/* CHOICE or ENUMERATED */\n");
+ buf_append(&state.parse_fns, "\ttoken_t next = next_token();\n\n");
+ buf_append(&state.parse_fns, "\t/* CHOICE or ENUMERATED */\n");
item = state.items;
for(item=state.items; item; item=item->next)
{
/* is it the first */
if(item == state.items)
- buf_append(&state.parser, "\t");
+ buf_append(&state.parse_fns, "\t");
else
- buf_append(&state.parser, "\telse ");
+ buf_append(&state.parse_fns, "\telse ");
if(item->type == IT_IDENTIFIER)
{
- buf_append(&state.parser, "if(is_%s(next))\n", item->name);
- buf_append(&state.parser, "\t\tparse_%s(state);\n", item->name);
+ buf_append(&state.parse_fns, "if(is_%s(next))\n", item->name);
+ buf_append(&state.parse_fns, "\t\tparse_%s(state);\n", item->name);
}
else if(item->type == IT_LITERAL)
{
char *tok_name = unquote(item->name);
- buf_append(&state.parser, "if(is_%s(next))\n", tok_name);
- buf_append(&state.parser, "\t\tparse_%s(state);\n", tok_name);
+ buf_append(&state.parse_fns, "if(is_%s(next))\n", tok_name);
+ buf_append(&state.parse_fns, "\t\tparse_%s(state);\n", tok_name);
free(tok_name);
}
else
@@ -388,42 +391,42 @@
fatal("CHOICE/ENUMERATED but not Identifier or Literal");
}
}
- buf_append(&state.parser, "\telse\n");
- buf_append(&state.parser, "\t\tparse_error(\"Unexpected token\");\n");
+ buf_append(&state.parse_fns, "\telse\n");
+ buf_append(&state.parse_fns, "\t\tparse_error(\"Unexpected token\");\n");
break;
case ASN1TYPE_SET:
/* assert */
if(!state.and_items)
fatal("SET but and_items not set");
- buf_append(&state.parser, "\ttoken_t next;\n\n");
+ buf_append(&state.parse_fns, "\ttoken_t next;\n\n");
item = state.items;
while(item && item->type == IT_LITERAL)
{
-buf_append(&state.parser, "// TODO: eat %s\n\n", item->name);
+buf_append(&state.parse_fns, "// TODO: eat %s\n\n", item->name);
item = item->next;
}
- buf_append(&state.parser, "\t/* SET */\n");
- buf_append(&state.parser, "\twhile(true)\n\t{\n");
- buf_append(&state.parser, "\t\tnext = next_token();\n");
+ buf_append(&state.parse_fns, "\t/* SET */\n");
+ buf_append(&state.parse_fns, "\twhile(true)\n\t{\n");
+ buf_append(&state.parse_fns, "\t\tnext = next_token();\n");
while(item && item->type != IT_LITERAL)
{
if(item->type != IT_IDENTIFIER && item->type != IT_OPTIONAL)
fatal("SET but not Identifier or Optional");
- buf_append(&state.parser, "\t\t/* %s */\n", item->name);
- buf_append(&state.parser, "\t\tif(is_%s(next))\n\t\t{\n", item->name);
- buf_append(&state.parser, "\t\t\tparse_%s(state);\n", item->name);
- buf_append(&state.parser, "\t\t\tcontinue;\n\t\t}\n");
+ buf_append(&state.parse_fns, "\t\t/* %s */\n", item->name);
+ buf_append(&state.parse_fns, "\t\tif(is_%s(next))\n\t\t{\n", item->name);
+ buf_append(&state.parse_fns, "\t\t\tparse_%s(state);\n", item->name);
+ buf_append(&state.parse_fns, "\t\t\tcontinue;\n\t\t}\n");
item = item->next;
}
/* didn't match any items, must be the end of the SET */
- buf_append(&state.parser, "\t\telse\n\t\t{\n");
- buf_append(&state.parser, "\t\t\tbreak;\n\t\t}\n");
- buf_append(&state.parser, "\t}\n");
+ buf_append(&state.parse_fns, "\t\telse\n\t\t{\n");
+ buf_append(&state.parse_fns, "\t\t\tbreak;\n\t\t}\n");
+ buf_append(&state.parse_fns, "\t}\n");
/* eat any trailing literals */
while(item && item->type == IT_LITERAL)
{
-buf_append(&state.parser, "\n// TODO: eat %s\n", item->name);
+buf_append(&state.parse_fns, "\n// TODO: eat %s\n", item->name);
item = item->next;
}
break;
@@ -432,27 +435,27 @@
/* assert */
if(!state.and_items)
fatal("SEQUENCE but and_items not set");
- buf_append(&state.parser, "\t/* SEQUENCE */\n");
- buf_append(&state.parser, "\ttoken_t next;\n");
+ buf_append(&state.parse_fns, "\t/* SEQUENCE */\n");
+ buf_append(&state.parse_fns, "\ttoken_t next;\n");
item = state.items;
for(item=state.items; item; item=item->next)
{
if(item->type != IT_IDENTIFIER && item->type != IT_LITERAL && item->type != IT_OPTIONAL)
fatal("SEQUENCE but not Identifier, Literal or Optional");
- buf_append(&state.parser, "\n\t/* %s */\n", item->name);
+ buf_append(&state.parse_fns, "\n\t/* %s */\n", item->name);
if(item->type == IT_LITERAL)
{
-buf_append(&state.parser, "// TODO: eat %s\n", item->name);
+buf_append(&state.parse_fns, "// TODO: eat %s\n", item->name);
}
else
{
- buf_append(&state.parser, "\tnext = next_token();\n");
- buf_append(&state.parser, "\tif(is_%s(next))\n", item->name);
- buf_append(&state.parser, "\t\tparse_%s(state);\n", item->name);
+ buf_append(&state.parse_fns, "\tnext = next_token();\n");
+ buf_append(&state.parse_fns, "\tif(is_%s(next))\n", item->name);
+ buf_append(&state.parse_fns, "\t\tparse_%s(state);\n", item->name);
if(item->type != IT_OPTIONAL)
{
- buf_append(&state.parser, "\telse\n");
- buf_append(&state.parser, "\t\tparse_error(\"Expecting %s\");\n", item->name);
+ buf_append(&state.parse_fns, "\telse\n");
+ buf_append(&state.parse_fns, "\t\tparse_error(\"Expecting %s\");\n", item->name);
}
}
}
@@ -463,7 +466,7 @@
break;
}
}
- buf_append(&state.parser, "}\n\n", name);
+ buf_append(&state.parse_fns, "}\n\n", name);
/* free the items */
item = state.items;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-08-29 15:09:35
|
Revision: 357
http://redbutton.svn.sourceforge.net/redbutton/?rev=357&view=rev
Author: skilvington
Date: 2007-08-29 08:09:30 -0700 (Wed, 29 Aug 2007)
Log Message:
-----------
generate is_Xxx() parser functions
Modified Paths:
--------------
redbutton-author/trunk/ccc.y
Modified: redbutton-author/trunk/ccc.y
===================================================================
--- redbutton-author/trunk/ccc.y 2007-08-28 20:41:58 UTC (rev 356)
+++ redbutton-author/trunk/ccc.y 2007-08-29 15:09:30 UTC (rev 357)
@@ -297,7 +297,7 @@
buf_append(&state.grammar, ";\n\n");
- /* C code for the parser */
+ /* C code for the parse_Xxx functions */
buf_append(&state.parse_fns, "void parse_%s(struct state *state)\n{\n", name);
/* count how many items make it up */
nitems = 0;
@@ -466,8 +466,77 @@
break;
}
}
- buf_append(&state.parse_fns, "}\n\n", name);
+ buf_append(&state.parse_fns, "}\n\n");
+ /* C code for the is_Xxx functions */
+ buf_append(&state.is_fns, "bool is_%s(token_t tok)\n{\n", name);
+ nitems = 0;
+ for(item=state.items; item; item=item->next)
+ nitems ++;
+ if(nitems == 1
+ || state.items->type == IT_LITERAL)
+ {
+ /* check if the first item matches the token */
+ item = state.items;
+ if(item->type == IT_LITERAL)
+ {
+ char *tok_name = unquote(item->name);
+ buf_append(&state.is_fns, "\treturn (tok == %s);\n", tok_name);
+ free(tok_name);
+ }
+ else
+ {
+ buf_append(&state.is_fns, "\treturn is_%s(tok);\n", item->name);
+ }
+ }
+ else
+ {
+ switch(asn1type(name))
+ {
+ case ASN1TYPE_CHOICE:
+ case ASN1TYPE_ENUMERATED:
+ case ASN1TYPE_SET:
+ /* check if any of the items match the token */
+ buf_append(&state.is_fns, "\treturn ");
+ for(item=state.items; item; item=item->next)
+ {
+ if(item->type != IT_IDENTIFIER && item->type != IT_OPTIONAL)
+ fatal("is_fns: expecting Identifier or [Identifier]");
+ buf_append(&state.is_fns, "is_%s(tok)", item->name);
+ /* is it the last one */
+ if(item->next)
+ buf_append(&state.is_fns, "\n\t || ");
+ else
+ buf_append(&state.is_fns, ";\n");
+ }
+ break;
+
+ case ASN1TYPE_SEQUENCE:
+ /* check if the first item matches the token */
+ item = state.items;
+ if(item->type == IT_LITERAL)
+ {
+ char *tok_name = unquote(item->name);
+ buf_append(&state.is_fns, "\treturn (tok == %s);\n", tok_name);
+ free(tok_name);
+ }
+ else if(item->type == IT_IDENTIFIER)
+ {
+ buf_append(&state.is_fns, "\treturn is_%s(tok);\n", item->name);
+ }
+ else
+ {
+ fatal("SEQUENCE but first item not Literal or Identifier");
+ }
+ break;
+
+ default:
+ fatal("Illegal ASN1TYPE");
+ break;
+ }
+ }
+ buf_append(&state.is_fns, "}\n\n");
+
/* free the items */
item = state.items;
while(item)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-08-29 16:07:54
|
Revision: 358
http://redbutton.svn.sourceforge.net/redbutton/?rev=358&view=rev
Author: skilvington
Date: 2007-08-29 09:07:46 -0700 (Wed, 29 Aug 2007)
Log Message:
-----------
generate parser header file
Modified Paths:
--------------
redbutton-author/trunk/ccc.y
Modified: redbutton-author/trunk/ccc.y
===================================================================
--- redbutton-author/trunk/ccc.y 2007-08-29 15:09:30 UTC (rev 357)
+++ redbutton-author/trunk/ccc.y 2007-08-29 16:07:46 UTC (rev 358)
@@ -55,6 +55,8 @@
struct str_list *oneormores; /* grammar section for Identifier+ rules */
struct buf parse_fns; /* parse_Xxx() C functions for the parser */
struct buf is_fns; /* is_Xxx() C functions for the parser */
+ struct buf parse_hdr; /* parse_Xxx() prototypes for the parser */
+ struct buf is_hdr; /* is_Xxx() C prototypes for the parser */
} state;
int yyparse(void);
@@ -179,9 +181,10 @@
char *prog_name = argv[0];
bool show_lexer = false;
bool show_parser = false;
+ bool show_header = false;
int arg;
- while((arg = getopt(argc, argv, "lp")) != EOF)
+ while((arg = getopt(argc, argv, "lph")) != EOF)
{
switch(arg)
{
@@ -193,6 +196,10 @@
show_parser = true;
break;
+ case 'h':
+ show_header = true;
+ break;
+
default:
usage(prog_name);
break;
@@ -209,6 +216,8 @@
state.oneormores = NULL;
buf_init(&state.parse_fns);
buf_init(&state.is_fns);
+ buf_init(&state.parse_hdr);
+ buf_init(&state.is_hdr);
yyparse();
@@ -223,6 +232,12 @@
printf("%s", state.parse_fns.str);
printf("%s", state.is_fns.str);
}
+ else if(show_header)
+ {
+ /* output C header file */
+ printf("%s", state.parse_hdr.str);
+ printf("%s", state.is_hdr.str);
+ }
else
{
/* output grammar */
@@ -239,7 +254,7 @@
void
usage(char *prog_name)
{
- fprintf(stderr, "Syntax: %s [-l] [-p]\n", prog_name);
+ fprintf(stderr, "Syntax: %s [-l|-p|-h]\n", prog_name);
exit(EXIT_FAILURE);
}
@@ -298,6 +313,7 @@
buf_append(&state.grammar, ";\n\n");
/* C code for the parse_Xxx functions */
+ buf_append(&state.parse_hdr, "void parse_%s(struct state *);\n", name);
buf_append(&state.parse_fns, "void parse_%s(struct state *state)\n{\n", name);
/* count how many items make it up */
nitems = 0;
@@ -469,6 +485,7 @@
buf_append(&state.parse_fns, "}\n\n");
/* C code for the is_Xxx functions */
+ buf_append(&state.is_hdr, "bool is_%s(token_t);\n", name);
buf_append(&state.is_fns, "bool is_%s(token_t tok)\n{\n", name);
nitems = 0;
for(item=state.items; item; item=item->next)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-08-30 08:31:08
|
Revision: 359
http://redbutton.svn.sourceforge.net/redbutton/?rev=359&view=rev
Author: skilvington
Date: 2007-08-30 01:30:55 -0700 (Thu, 30 Aug 2007)
Log Message:
-----------
generate is_Xxx functions for the tokens
Modified Paths:
--------------
redbutton-author/trunk/ccc.y
Modified: redbutton-author/trunk/ccc.y
===================================================================
--- redbutton-author/trunk/ccc.y 2007-08-29 16:07:46 UTC (rev 358)
+++ redbutton-author/trunk/ccc.y 2007-08-30 08:30:55 UTC (rev 359)
@@ -183,6 +183,7 @@
bool show_parser = false;
bool show_header = false;
int arg;
+ struct str_list *t;
while((arg = getopt(argc, argv, "lph")) != EOF)
{
@@ -237,6 +238,9 @@
/* output C header file */
printf("%s", state.parse_hdr.str);
printf("%s", state.is_hdr.str);
+ /* add is_Xxx functions for the tokens */
+ for(t=state.tokens; t; t=t->next)
+ printf("#define is_%s(TOK)\t(TOK == %s)\n", t->name, t->name);
}
else
{
@@ -498,7 +502,7 @@
if(item->type == IT_LITERAL)
{
char *tok_name = unquote(item->name);
- buf_append(&state.is_fns, "\treturn (tok == %s);\n", tok_name);
+ buf_append(&state.is_fns, "\treturn is_%s(tok);\n", tok_name);
free(tok_name);
}
else
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-08-31 13:56:42
|
Revision: 366
http://redbutton.svn.sourceforge.net/redbutton/?rev=366&view=rev
Author: skilvington
Date: 2007-08-31 06:56:33 -0700 (Fri, 31 Aug 2007)
Log Message:
-----------
remove unused code
Modified Paths:
--------------
redbutton-author/trunk/ccc.y
Modified: redbutton-author/trunk/ccc.y
===================================================================
--- redbutton-author/trunk/ccc.y 2007-08-31 13:44:42 UTC (rev 365)
+++ redbutton-author/trunk/ccc.y 2007-08-31 13:56:33 UTC (rev 366)
@@ -27,7 +27,6 @@
struct item *next;
char *name;
enum item_type type;
- bool include; /* should we output this optional item or not */
};
/* a list of strings */
@@ -350,7 +349,6 @@
new_item->next = NULL;
new_item->name = name; /* lex strdup's it for us */
new_item->type = type;
- new_item->include = true;
/* if it is a literal, make a token for it */
if(new_item->type == IT_LITERAL)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-08-31 16:09:34
|
Revision: 367
http://redbutton.svn.sourceforge.net/redbutton/?rev=367&view=rev
Author: skilvington
Date: 2007-08-31 07:29:38 -0700 (Fri, 31 Aug 2007)
Log Message:
-----------
tidy up the comments now it's all settled down a bit
Modified Paths:
--------------
redbutton-author/trunk/ccc.y
Modified: redbutton-author/trunk/ccc.y
===================================================================
--- redbutton-author/trunk/ccc.y 2007-08-31 13:56:33 UTC (rev 366)
+++ redbutton-author/trunk/ccc.y 2007-08-31 14:29:38 UTC (rev 367)
@@ -36,7 +36,7 @@
char *name;
};
-/* build up the separate parts of the output file in these buffers */
+/* build up the separate parts of the output files in these buffers */
struct buf
{
char *str; /* the buffer */
@@ -50,13 +50,13 @@
struct item *items; /* NULL => start a new identifier */
bool and_items; /* true => identifier must contain all items */
struct buf lexer; /* lex output file */
- struct str_list *tokens; /* "%token" section of the yacc output file */
+ struct str_list *tokens; /* tokens returned by the lexer */
struct buf parse_fns; /* parse_Xxx() C functions for the parser */
- struct buf parse_enum_fns; /* parse_Xxx() functions for enum values */
+ struct buf parse_enum_fns; /* parse_Xxx() C functions for enum values */
struct buf is_fns; /* is_Xxx() C functions for the parser */
struct buf parse_hdr; /* parse_Xxx() prototypes for the parser */
struct buf parse_enum_hdr; /* parse_Xxx() prototypes for enum values */
- struct buf is_hdr; /* is_Xxx() C prototypes for the parser */
+ struct buf is_hdr; /* is_Xxx() prototypes for the parser */
} state;
/* header for files we generate */
@@ -296,7 +296,7 @@
snprintf(header, sizeof(header), "%s.header", tokens_name);
file_append(tokens_file, header);
/* output our stuff */
- tok_val = 256;
+ tok_val = 256; // just needs to be larger than the last one in tokens.h.header
for(t=state.tokens; t; t=t->next)
fprintf(tokens_file, "#define %s\t%u\n", t->name, tok_val++);
/* output the footer if there is one */
@@ -333,13 +333,13 @@
if(new_item == NULL || name == NULL)
fatal("Out of memory");
+ /* find the end of the list */
if(state.items == NULL)
{
state.items = new_item;
}
else
{
- /* find the end of the list */
struct item *i = state.items;
while(i->next)
i = i->next;
@@ -364,11 +364,14 @@
struct item *next;
unsigned int nitems;
+ /* prototype for the parse_Xxx function */
+ buf_append(&state.parse_hdr, "void parse_%s(struct state *);\n", name);
+
/* C code for the parse_Xxx functions */
- buf_append(&state.parse_hdr, "void parse_%s(struct state *);\n", name);
buf_append(&state.parse_fns, "void parse_%s(struct state *state)\n{\n", name);
buf_append(&state.parse_fns, "\ttoken_t next;\n\n");
buf_append(&state.parse_fns, "\tverbose(\"<%s>\\n\");\n\n", name);
+
/* count how many items make it up */
nitems = 0;
/* skip literals at the start */
@@ -381,8 +384,11 @@
nitems ++;
item = item->next;
}
+
+ /* a single item (not including literals) */
if(nitems == 1)
{
+ /* eat literals at the start */
item = state.items;
while(item && item->type == IT_LITERAL)
{
@@ -392,6 +398,7 @@
free(tok_name);
item = item->next;
}
+ /* see if the next token is what we are expecting */
buf_append(&state.parse_fns, "\tnext = peek_token();\n\n");
if(item->type == IT_IDENTIFIER)
{
@@ -418,8 +425,10 @@
}
else
{
+ /* assert */
fatal("nitems==1 but not Identifier/[Identifier]/Identifier+");
}
+ /* eat literals at the end */
item = item->next;
while(item)
{
@@ -430,8 +439,16 @@
item = item->next;
}
}
+ /* more than one item (not including literals) */
else
{
+ /*
+ * do we need to pick one item, or do we need them all?
+ * ie are we building a CHOICE/ENUMERATED or a SET/SEQUENCE type
+ * does the order in which the items appear matter?
+ * ie are we building an ordered (SEQUENCE) or unordered (SET) type
+ */
+/* TODO: could probably just check and_items rather than doing asn1type() now we know the grammar is consistent */
switch(asn1type(name))
{
case ASN1TYPE_CHOICE:
@@ -457,11 +474,12 @@
else if(item->type == IT_LITERAL)
{
char *tok_name = unquote(item->name);
+ /* assert */
+ if(asn1type(name) != ASN1TYPE_ENUMERATED)
+ fatal("literal but not enum");
buf_append(&state.parse_fns, "if(is_%s(next))\n", tok_name);
buf_append(&state.parse_fns, "\t\tparse_%s(state);\n", tok_name);
/* create a parse_Xxx function for the enum value */
- if(asn1type(name) != ASN1TYPE_ENUMERATED)
- fatal("literal but not enum");
buf_append(&state.parse_enum_hdr, "void parse_%s(struct state *);\n", tok_name);
buf_append(&state.parse_enum_fns, "void parse_%s(struct state *state)\n{\n", tok_name);
buf_append(&state.parse_enum_fns, "\texpect_token(%s, %s);\n", tok_name, item->name);
@@ -471,6 +489,7 @@
}
else
{
+ /* assert */
fatal("CHOICE/ENUMERATED but not Identifier or Literal");
}
}
@@ -482,6 +501,7 @@
/* assert */
if(!state.and_items)
fatal("SET but and_items not set");
+ /* eat any literals at the start */
item = state.items;
while(item && item->type == IT_LITERAL)
{
@@ -491,11 +511,13 @@
free(tok_name);
item = item->next;
}
+ /* keep parsing items until we get one that should not be in the SET */
buf_append(&state.parse_fns, "\t/* SET */\n");
buf_append(&state.parse_fns, "\twhile(true)\n\t{\n");
buf_append(&state.parse_fns, "\t\tnext = peek_token();\n");
while(item && item->type != IT_LITERAL)
{
+ /* assert */
if(item->type != IT_IDENTIFIER && item->type != IT_OPTIONAL)
fatal("SET but not Identifier or Optional");
buf_append(&state.parse_fns, "\t\t/* %s */\n", item->name);
@@ -527,8 +549,10 @@
item = state.items;
for(item=state.items; item; item=item->next)
{
+ /* assert */
if(item->type != IT_IDENTIFIER && item->type != IT_LITERAL && item->type != IT_OPTIONAL)
fatal("SEQUENCE but not Identifier, Literal or Optional");
+ /* eat literals, parse [optional] identifiers */
buf_append(&state.parse_fns, "\n\t/* %s */\n", item->name);
if(item->type == IT_LITERAL)
{
@@ -551,6 +575,7 @@
break;
default:
+ /* assert */
fatal("Illegal ASN1TYPE");
break;
}
@@ -558,22 +583,40 @@
buf_append(&state.parse_fns, "\n\tverbose(\"</%s>\\n\");\n", name);
buf_append(&state.parse_fns, "\n\treturn;\n}\n\n");
+ /*
+ * generate the is_Xxx(token_t) functions
+ * these functions should return true if the given token can be the first token for this type
+ * for unordered types (SET/CHOICE/ENUMERATED) check if any of the items match the token
+ * for ordered types (SEQUENCE) check if the first item matches the token
+ */
+
+ /* prototype for the is_Xxx functions */
+ buf_append(&state.is_hdr, "bool is_%s(token_t);\n", name);
+
/* C code for the is_Xxx functions */
- buf_append(&state.is_hdr, "bool is_%s(token_t);\n", name);
buf_append(&state.is_fns, "bool is_%s(token_t tok)\n{\n", name);
+
+ /* count the number of items */
nitems = 0;
for(item=state.items; item; item=item->next)
nitems ++;
+
+ /*
+ * for single items (or ones that start with a literal) the token must match the first item
+ * unless it's an ENUMERATED type,
+ * in which case all items are literals and the token can match any of them
+ */
if(nitems == 1
|| state.items->type == IT_LITERAL)
{
- /* if it is an enum, check if any item matches the token */
+ /* if it is an enum, check if any of the enum items match the token */
bool is_enum = true;
for(item=state.items; item && is_enum; item=item->next)
is_enum = is_enum && (item->type == IT_LITERAL);
item = state.items;
if(is_enum)
{
+ /* assert */
if(asn1type(name) != ASN1TYPE_ENUMERATED)
fatal("is_enum but not ENUMERATED");
buf_append(&state.is_fns, "\treturn ");
@@ -590,7 +633,7 @@
item = item->next;
}
}
- /* just check if the first item matches the token */
+ /* not an enum, just check if the first item matches the token */
else if(item->type == IT_LITERAL)
{
char *tok_name = unquote(item->name);
@@ -606,13 +649,15 @@
{
switch(asn1type(name))
{
+/* TODO: we have taken care of ENUMERATED above */
+ case ASN1TYPE_ENUMERATED:
case ASN1TYPE_CHOICE:
- case ASN1TYPE_ENUMERATED:
case ASN1TYPE_SET:
/* check if any of the items match the token */
buf_append(&state.is_fns, "\treturn ");
for(item=state.items; item; item=item->next)
{
+ /* assert */
if(item->type != IT_IDENTIFIER && item->type != IT_OPTIONAL)
fatal("is_fns: expecting Identifier or [Identifier]");
buf_append(&state.is_fns, "is_%s(tok)", item->name);
@@ -639,11 +684,13 @@
}
else
{
+ /* assert */
fatal("SEQUENCE but first item not Literal or Identifier");
}
break;
default:
+ /* assert */
fatal("Illegal ASN1TYPE");
break;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-09-08 17:32:33
|
Revision: 369
http://redbutton.svn.sourceforge.net/redbutton/?rev=369&view=rev
Author: skilvington
Date: 2007-09-08 10:32:26 -0700 (Sat, 08 Sep 2007)
Log Message:
-----------
find the value of enum names
Modified Paths:
--------------
redbutton-author/trunk/ccc.y
Modified: redbutton-author/trunk/ccc.y
===================================================================
--- redbutton-author/trunk/ccc.y 2007-08-31 14:56:23 UTC (rev 368)
+++ redbutton-author/trunk/ccc.y 2007-09-08 17:32:26 UTC (rev 369)
@@ -363,6 +363,7 @@
struct item *item;
struct item *next;
unsigned int nitems;
+ unsigned int enum_val;
/* prototype for the parse_Xxx function */
buf_append(&state.parse_hdr, "void parse_%s(struct state *);\n", name);
@@ -458,6 +459,8 @@
fatal("CHOICE or ENUMERATED type, but and_items set");
buf_append(&state.parse_fns, "\tnext = peek_token();\n\n");
buf_append(&state.parse_fns, "\t/* CHOICE or ENUMERATED */\n");
+ /* enum values all start at 1 and are listed in order in the grammar */
+ enum_val = 1;
item = state.items;
for(item=state.items; item; item=item->next)
{
@@ -483,9 +486,10 @@
buf_append(&state.parse_enum_hdr, "void parse_%s(struct state *);\n", tok_name);
buf_append(&state.parse_enum_fns, "void parse_%s(struct state *state)\n{\n", tok_name);
buf_append(&state.parse_enum_fns, "\texpect_token(%s, %s);\n", tok_name, item->name);
- buf_append(&state.parse_enum_fns, "\n\tverbose(\"<ENUM value=%s/>\\n\");\n", tok_name);
+ buf_append(&state.parse_enum_fns, "\n\tverbose(\"<ENUM name=%s value=%u/>\\n\");\n", tok_name, enum_val);
buf_append(&state.parse_enum_fns, "\n\treturn;\n}\n\n");
free(tok_name);
+ enum_val ++;
}
else
{
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-09-10 08:45:01
|
Revision: 370
http://redbutton.svn.sourceforge.net/redbutton/?rev=370&view=rev
Author: skilvington
Date: 2007-09-10 01:44:58 -0700 (Mon, 10 Sep 2007)
Log Message:
-----------
print the real names of enums, not the names of their lex tokens
Modified Paths:
--------------
redbutton-author/trunk/ccc.y
Modified: redbutton-author/trunk/ccc.y
===================================================================
--- redbutton-author/trunk/ccc.y 2007-09-08 17:32:26 UTC (rev 369)
+++ redbutton-author/trunk/ccc.y 2007-09-10 08:44:58 UTC (rev 370)
@@ -486,7 +486,7 @@
buf_append(&state.parse_enum_hdr, "void parse_%s(struct state *);\n", tok_name);
buf_append(&state.parse_enum_fns, "void parse_%s(struct state *state)\n{\n", tok_name);
buf_append(&state.parse_enum_fns, "\texpect_token(%s, %s);\n", tok_name, item->name);
- buf_append(&state.parse_enum_fns, "\n\tverbose(\"<ENUM name=%s value=%u/>\\n\");\n", tok_name, enum_val);
+ buf_append(&state.parse_enum_fns, "\n\tverbose(\"<ENUM name=\\\"\"%s\"\\\" value=%u/>\\n\");\n", item->name, enum_val);
buf_append(&state.parse_enum_fns, "\n\treturn;\n}\n\n");
free(tok_name);
enum_val ++;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-09-16 09:39:53
|
Revision: 383
http://redbutton.svn.sourceforge.net/redbutton/?rev=383&view=rev
Author: skilvington
Date: 2007-09-16 02:39:52 -0700 (Sun, 16 Sep 2007)
Log Message:
-----------
something to think about
Modified Paths:
--------------
redbutton-author/trunk/ccc.y
Modified: redbutton-author/trunk/ccc.y
===================================================================
--- redbutton-author/trunk/ccc.y 2007-09-16 09:36:30 UTC (rev 382)
+++ redbutton-author/trunk/ccc.y 2007-09-16 09:39:52 UTC (rev 383)
@@ -459,6 +459,7 @@
/* assert */
if(state.and_items)
fatal("CHOICE or ENUMERATED type, but and_items set");
+/* TODO: these can probably both be ASN1TAGCLASS_SYNTHETIC */
/* add a child ASN1 object */
if(asn1type(name) == ASN1TYPE_CHOICE)
buf_append(&state.parse_fns, "\tparent = add_child(parent, ASN1TAG_CHOICE);\n\n");
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-09-21 16:26:50
|
Revision: 409
http://redbutton.svn.sourceforge.net/redbutton/?rev=409&view=rev
Author: skilvington
Date: 2007-09-21 09:26:48 -0700 (Fri, 21 Sep 2007)
Log Message:
-----------
make the auto-generated code look beautiful!
Modified Paths:
--------------
redbutton-author/trunk/ccc.y
Modified: redbutton-author/trunk/ccc.y
===================================================================
--- redbutton-author/trunk/ccc.y 2007-09-21 16:17:21 UTC (rev 408)
+++ redbutton-author/trunk/ccc.y 2007-09-21 16:26:48 UTC (rev 409)
@@ -436,8 +436,8 @@
while(item)
{
char *tok_name = unquote(item->name);
- buf_append(&state.parse_fns, "\t/* %s */\n", item->name);
- buf_append(&state.parse_fns, "\texpect_token(%s, %s);\n\n", tok_name, item->name);
+ buf_append(&state.parse_fns, "\n\t/* %s */\n", item->name);
+ buf_append(&state.parse_fns, "\texpect_token(%s, %s);\n", tok_name, item->name);
free(tok_name);
item = item->next;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|