[Redbutton-devel] SF.net SVN: redbutton: [354] redbutton-author/trunk
Brought to you by:
skilvington
|
From: <ski...@us...> - 2007-08-28 16:16:02
|
Revision: 354
http://redbutton.svn.sourceforge.net/redbutton/?rev=354&view=rev
Author: skilvington
Date: 2007-08-28 09:15:53 -0700 (Tue, 28 Aug 2007)
Log Message:
-----------
try generating C code for the compiler rather than a yacc grammar
Modified Paths:
--------------
redbutton-author/trunk/Makefile
redbutton-author/trunk/ccc.y
Added Paths:
-----------
redbutton-author/trunk/asn1type.c
redbutton-author/trunk/asn1type.h
Modified: redbutton-author/trunk/Makefile
===================================================================
--- redbutton-author/trunk/Makefile 2007-08-26 10:40:33 UTC (rev 353)
+++ redbutton-author/trunk/Makefile 2007-08-28 16:15:53 UTC (rev 354)
@@ -23,10 +23,10 @@
parser.tab.h: parser.tab.c
-ccc: ccc.y ccc.l
+ccc: ccc.y ccc.l asn1type.o
${LEX} -i -t ccc.l > lex.ccc.c
${YACC} -b ccc -d ccc.y
- ${CC} ${CFLAGS} -o ccc lex.ccc.c ccc.tab.c
+ ${CC} ${CFLAGS} -o ccc lex.ccc.c ccc.tab.c asn1type.o
parser.l: parser.l.header parser.l.footer grammar ccc
cat parser.l.header > parser.l
Added: redbutton-author/trunk/asn1type.c
===================================================================
--- redbutton-author/trunk/asn1type.c (rev 0)
+++ redbutton-author/trunk/asn1type.c 2007-08-28 16:15:53 UTC (rev 354)
@@ -0,0 +1,220 @@
+/*
+ * asn1type.c
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "asn1type.h"
+
+#define MATCH(NAME, TYPE) if(strcmp(name, #NAME) == 0) return ASN1TYPE_ ## TYPE;
+
+enum asn1type
+asn1type(char *name)
+{
+ MATCH(InterchangedObject, CHOICE)
+ MATCH(Group, SET) // MATCH(GroupClass, SET)
+ MATCH(StandardIdentifier, SEQUENCE)
+ MATCH(GroupItem, CHOICE)
+ MATCH(ApplicationClass, SET)
+ MATCH(DefaultAttribute, CHOICE)
+ MATCH(FontBody, CHOICE)
+ MATCH(SceneClass, SET)
+ MATCH(SceneCoordinateSystem, SEQUENCE)
+ MATCH(AspectRatio, SEQUENCE)
+ MATCH(NextScene, SEQUENCE)
+ MATCH(Ingredient, SET) // MATCH(IngredientClass, SET)
+ MATCH(ContentBody, CHOICE)
+ MATCH(ReferencedContent, SEQUENCE)
+ MATCH(LinkClass, SET)
+ MATCH(LinkCondition, SEQUENCE)
+ MATCH(EventTypeEnum, ENUMERATED) // MATCH(EventType, ENUMERATED)
+ MATCH(EventDataBody, CHOICE) // MATCH(EventData, CHOICE)
+ MATCH(Program, SET) // MATCH(ProgramClass, SET)
+ MATCH(ResidentProgramClass, SET)
+ MATCH(RemoteProgramClass, SET)
+ MATCH(InterchangedProgramClass, SET)
+ MATCH(PaletteClass, SET)
+ MATCH(FontClass, SET)
+ MATCH(CursorShapeClass, SET)
+ MATCH(Variable, SET) // MATCH(VariableClass, SET)
+ MATCH(OriginalValueBody, CHOICE) // MATCH(OriginalValue, CHOICE)
+ MATCH(BooleanVariableClass, SET)
+ MATCH(IntegerVariableClass, SET)
+ MATCH(OctetStringVariableClass, SET)
+ MATCH(ObjectRefVariableClass, SET)
+ MATCH(ContentRefVariableClass, SET)
+ MATCH(PresentableClass, SET)
+ MATCH(TokenManagerClass, SET)
+ MATCH(Movement, SEQUENCE)
+ MATCH(TokenGroupBody, SET) // MATCH(TokenGroupClass, SET)
+ MATCH(TokenGroupItem, SEQUENCE)
+ MATCH(ActionSlot, CHOICE)
+ MATCH(ListGroupClass, SET)
+ MATCH(Visible, SET) // MATCH(VisibleClass, SET)
+ MATCH(BoxSize, SEQUENCE) // MATCH(OriginalBoxSize, SEQUENCE)
+ MATCH(BitmapClass, SET)
+ MATCH(LineArtBody, SET) // MATCH(LineArtClass, SET)
+ MATCH(RectangleClass, SET)
+ MATCH(DynamicLineArtClass, SET)
+ MATCH(TextBody, SET) // MATCH(TextClass, SET)
+ MATCH(JustificationEnum, ENUMERATED) // MATCH(Justification, ENUMERATED)
+ MATCH(LineOrientationEnum, ENUMERATED) // MATCH(LineOrientation, ENUMERATED)
+ MATCH(StartCornerEnum, ENUMERATED) // MATCH(StartCorner, ENUMERATED)
+ MATCH(StreamClass, SET)
+ MATCH(StreamComponent, CHOICE)
+ MATCH(StorageEnum, ENUMERATED) // MATCH(Storage, ENUMERATED)
+ MATCH(AudioClass, SET)
+ MATCH(VideoClass, SET)
+ MATCH(TerminationEnum, ENUMERATED) // MATCH(Termination, ENUMERATED)
+ MATCH(RTGraphicsClass, SET)
+ MATCH(Interactible, SET) // MATCH(InteractibleClass, SET)
+ MATCH(SliderClass, SET)
+ MATCH(OrientationEnum, ENUMERATED) // MATCH(Orientation, ENUMERATED)
+ MATCH(SliderStyleEnum, ENUMERATED) // MATCH(SliderStyle, ENUMERATED)
+ MATCH(EntryFieldClass, SET)
+ MATCH(InputTypeEnum, ENUMERATED) // MATCH(InputType, ENUMERATED)
+ MATCH(HyperTextClass, SET)
+ MATCH(Button, SET) // MATCH(ButtonClass, SET)
+ MATCH(HotspotClass, SET)
+ MATCH(PushButtonBody, SET) // MATCH(PushButtonClass, SET)
+ MATCH(SwitchButtonClass, SET)
+ MATCH(ButtonStyleEnum, ENUMERATED) // MATCH(ButtonStyle, ENUMERATED)
+ MATCH(ActionClass, SEQUENCE)
+ MATCH(ElementaryAction, CHOICE)
+ MATCH(Add, SEQUENCE)
+ MATCH(AddItem, SEQUENCE)
+ MATCH(Append, SEQUENCE)
+ MATCH(Call, SEQUENCE)
+ MATCH(CallActionSlot, SEQUENCE)
+ MATCH(Clone, SEQUENCE)
+ MATCH(CloseConnection, SEQUENCE)
+ MATCH(DelItem, SEQUENCE)
+ MATCH(DeselectItem, SEQUENCE)
+ MATCH(Divide, SEQUENCE)
+ MATCH(DrawArc, SEQUENCE)
+ MATCH(DrawLine, SEQUENCE)
+ MATCH(DrawOval, SEQUENCE)
+ MATCH(DrawPolygon, SEQUENCE)
+ MATCH(DrawPolyline, SEQUENCE)
+ MATCH(DrawRectangle, SEQUENCE)
+ MATCH(DrawSector, SEQUENCE)
+ MATCH(Fork, SEQUENCE)
+ MATCH(GetAvailabilityStatus, SEQUENCE)
+ MATCH(GetBoxSize, SEQUENCE)
+ MATCH(GetCellItem, SEQUENCE)
+ MATCH(GetCursorPosition, SEQUENCE)
+ MATCH(GetEngineSupport, SEQUENCE)
+ MATCH(GetEntryPoint, SEQUENCE)
+ MATCH(GetFillColour, SEQUENCE)
+ MATCH(GetFirstItem, SEQUENCE)
+ MATCH(GetHighlightStatus, SEQUENCE)
+ MATCH(GetInteractionStatus, SEQUENCE)
+ MATCH(GetItemStatus, SEQUENCE)
+ MATCH(GetLabel, SEQUENCE)
+ MATCH(GetLastAnchorFired, SEQUENCE)
+ MATCH(GetLineColour, SEQUENCE)
+ MATCH(GetLineStyle, SEQUENCE)
+ MATCH(GetLineWidth, SEQUENCE)
+ MATCH(GetListItem, SEQUENCE)
+ MATCH(GetListSize, SEQUENCE)
+ MATCH(GetOverwriteMode, SEQUENCE)
+ MATCH(GetPortion, SEQUENCE)
+ MATCH(GetPosition, SEQUENCE)
+ MATCH(GetRunningStatus, SEQUENCE)
+ MATCH(GetSelectionStatus, SEQUENCE)
+ MATCH(GetSliderValue, SEQUENCE)
+ MATCH(GetTextContent, SEQUENCE)
+ MATCH(GetTextData, SEQUENCE)
+ MATCH(GetTokenPosition, SEQUENCE)
+ MATCH(GetVolume, SEQUENCE)
+ MATCH(Modulo, SEQUENCE)
+ MATCH(Move, SEQUENCE)
+ MATCH(MoveTo, SEQUENCE)
+ MATCH(Multiply, SEQUENCE)
+ MATCH(OpenConnection, SEQUENCE)
+ MATCH(PutBefore, SEQUENCE)
+ MATCH(PutBehind, SEQUENCE)
+ MATCH(ReadPersistent, SEQUENCE)
+ MATCH(ScaleBitmap, SEQUENCE)
+ MATCH(ScaleVideo, SEQUENCE)
+ MATCH(ScrollItems, SEQUENCE)
+ MATCH(SelectItem, SEQUENCE)
+ MATCH(SendEvent, SEQUENCE)
+ MATCH(SetBoxSize, SEQUENCE)
+ MATCH(SetCachePriority, SEQUENCE)
+ MATCH(SetCounterEndPosition, SEQUENCE)
+ MATCH(SetCounterPosition, SEQUENCE)
+ MATCH(SetCounterTrigger, SEQUENCE)
+ MATCH(SetCursorPosition, SEQUENCE)
+ MATCH(SetCursorShape, SEQUENCE)
+ MATCH(SetData, SEQUENCE)
+ MATCH(SetEntryPoint, SEQUENCE)
+ MATCH(SetFillColour, SEQUENCE)
+ MATCH(SetFirstItem, SEQUENCE)
+ MATCH(SetFontRef, SEQUENCE)
+ MATCH(SetHighlightStatus, SEQUENCE)
+ MATCH(SetInteractionStatus, SEQUENCE)
+ MATCH(SetLabel, SEQUENCE)
+ MATCH(SetLineColour, SEQUENCE)
+ MATCH(SetLineStyle, SEQUENCE)
+ MATCH(SetLineWidth, SEQUENCE)
+ MATCH(SetOverwriteMode, SEQUENCE)
+ MATCH(SetPaletteRef, SEQUENCE)
+ MATCH(SetPortion, SEQUENCE)
+ MATCH(SetPosition, SEQUENCE)
+ MATCH(SetSliderValue, SEQUENCE)
+ MATCH(SetSpeed, SEQUENCE)
+ MATCH(SetTimer, SEQUENCE)
+ MATCH(NewTimer, SEQUENCE)
+ MATCH(SetTransparency, SEQUENCE)
+ MATCH(SetVariable, SEQUENCE)
+ MATCH(SetVolume, SEQUENCE)
+ MATCH(Step, SEQUENCE)
+ MATCH(StorePersistent, SEQUENCE)
+ MATCH(Subtract, SEQUENCE)
+ MATCH(TestVariable, SEQUENCE)
+ MATCH(ToggleItem, SEQUENCE)
+ MATCH(TransitionTo, SEQUENCE)
+ MATCH(ConnectionTagOrNull, CHOICE)
+ MATCH(ComparisonValue, CHOICE)
+ MATCH(EmulatedEventData, CHOICE)
+ MATCH(NewColour, CHOICE)
+ MATCH(NewContent, CHOICE)
+ MATCH(NewFont, CHOICE)
+ MATCH(NewReferencedContent, SEQUENCE)
+ MATCH(NewContentSize, CHOICE)
+ MATCH(NewVariableValue, CHOICE)
+ MATCH(Parameter, CHOICE)
+ MATCH(Point, SEQUENCE)
+ MATCH(Rational, SEQUENCE)
+ MATCH(ObjectReference, CHOICE)
+ MATCH(ExternalReference, SEQUENCE)
+ MATCH(IndirectReference, CHOICE)
+ MATCH(GenericObjectReference, CHOICE)
+ MATCH(GenericContentReference, CHOICE)
+ MATCH(GenericInteger, CHOICE)
+ MATCH(GenericBoolean, CHOICE)
+ MATCH(GenericOctetString, CHOICE)
+ MATCH(Colour, CHOICE)
+ MATCH(XYPosition, SEQUENCE)
+ MATCH(SetInputReg, SEQUENCE) // MATCH(SetInputRegister, SEQUENCE)
+ MATCH(SetCellPosition, SEQUENCE)
+ MATCH(SetBitmapDecodeOffset, SEQUENCE)
+ MATCH(GetBitmapDecodeOffset, SEQUENCE)
+ MATCH(SetBackgroundColour, SEQUENCE)
+ MATCH(SetTextColour, SEQUENCE)
+ MATCH(SetFontAttributes, SEQUENCE)
+ MATCH(SetVideoDecodeOffset, SEQUENCE)
+ MATCH(GetVideoDecodeOffset, SEQUENCE)
+ MATCH(SetSliderParameters, SEQUENCE)
+ MATCH(GetFocusPosition, SEQUENCE)
+ MATCH(SetFocusPosition, SEQUENCE)
+ MATCH(OctetString, CHOICE);
+
+ fprintf(stderr, "Unknown ASN1 type: %s\n", name);
+ exit(EXIT_FAILURE);
+
+ return ASN1TYPE_UNKNOWN;
+}
Added: redbutton-author/trunk/asn1type.h
===================================================================
--- redbutton-author/trunk/asn1type.h (rev 0)
+++ redbutton-author/trunk/asn1type.h 2007-08-28 16:15:53 UTC (rev 354)
@@ -0,0 +1,19 @@
+/*
+ * asn1type.h
+ */
+
+#ifndef __ASN1TYPE_H__
+#define __ASN1TYPE_H__
+
+enum asn1type
+{
+ ASN1TYPE_UNKNOWN,
+ ASN1TYPE_CHOICE,
+ ASN1TYPE_ENUMERATED,
+ ASN1TYPE_SET,
+ ASN1TYPE_SEQUENCE
+};
+
+enum asn1type asn1type(char *);
+
+#endif /* __ASN1TYPE_H__ */
Modified: redbutton-author/trunk/ccc.y
===================================================================
--- redbutton-author/trunk/ccc.y 2007-08-26 10:40:33 UTC (rev 353)
+++ redbutton-author/trunk/ccc.y 2007-08-28 16:15:53 UTC (rev 354)
@@ -8,6 +8,8 @@
#include <stdarg.h>
#include <ctype.h>
+#include "asn1type.h"
+
#define YYSTYPE char *
/* build up a list of items that define the current identifier */
@@ -51,6 +53,7 @@
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 */
} state;
int yyparse(void);
@@ -173,11 +176,11 @@
main(int argc, char *argv[])
{
char *prog_name = argv[0];
- /* by default output the grammar */
bool show_lexer = false;
+ bool show_parser = false;
int arg;
- while((arg = getopt(argc, argv, "l")) != EOF)
+ while((arg = getopt(argc, argv, "lp")) != EOF)
{
switch(arg)
{
@@ -185,6 +188,10 @@
show_lexer = true;
break;
+ case 'p':
+ show_parser = true;
+ break;
+
default:
usage(prog_name);
break;
@@ -199,6 +206,7 @@
state.tokens = NULL;
buf_init(&state.grammar);
state.oneormores = NULL;
+ buf_init(&state.parser);
yyparse();
@@ -207,6 +215,11 @@
/* output lexer */
printf("%s", state.lexer.str);
}
+ else if(show_parser)
+ {
+ /* output C code */
+ printf("%s", state.parser.str);
+ }
else
{
/* output grammar */
@@ -223,7 +236,7 @@
void
usage(char *prog_name)
{
- fprintf(stderr, "Syntax: %s [-l]\n", prog_name);
+ fprintf(stderr, "Syntax: %s [-l] [-p]\n", prog_name);
exit(EXIT_FAILURE);
}
@@ -271,6 +284,7 @@
{
struct item *item;
struct item *next;
+ unsigned int nitems;
buf_append(&state.grammar, "%s:\n\t", name);
@@ -280,6 +294,155 @@
buf_append(&state.grammar, ";\n\n");
+ /* C code for the parser */
+ buf_append(&state.parser, "void parse_%s(struct state *state)\n{\n", name);
+ /* count how many items make it up */
+ nitems = 0;
+ /* skip literals at the start */
+ item = state.items;
+ while(item && item->type == IT_LITERAL)
+ item = item->next;
+ /* don't count literals at the end */
+ while(item && item->type != IT_LITERAL)
+ {
+ nitems ++;
+ item = item->next;
+ }
+ if(nitems == 1)
+ {
+ item = state.items;
+ while(item && item->type == IT_LITERAL)
+ {
+buf_append(&state.parser, "// TODO: eat %s\n\n", item->name);
+ item = item->next;
+ }
+ buf_append(&state.parser, "\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);
+ }
+ 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);
+ }
+ 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");
+ }
+ else
+ {
+ fatal("nitems==1 but not Identifier/[Identifier]/Identifier+");
+ }
+ item = item->next;
+ while(item)
+ {
+buf_append(&state.parser, "\n// TODO: eat %s\n", item->name);
+ item = item->next;
+ }
+ }
+ else
+ {
+ switch(asn1type(name))
+ {
+ case ASN1TYPE_CHOICE:
+ case ASN1TYPE_ENUMERATED:
+ /* 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");
+ item = state.items;
+ for(item=state.items; item; item=item->next)
+ {
+ /* is it the first */
+ if(item == state.items)
+ buf_append(&state.parser, "\t");
+ else
+ buf_append(&state.parser, "\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);
+ }
+ 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);
+ free(tok_name);
+ }
+ else
+ {
+ fatal("CHOICE/ENUMERATED but not Identifier or Literal");
+ }
+ }
+ buf_append(&state.parser, "\telse\n");
+ buf_append(&state.parser, "\t\tparse_error(\"Unexpected token\");\n");
+ break;
+
+ case ASN1TYPE_SET:
+ /* assert */
+ if(!state.and_items)
+ fatal("SET type, but and_items not set");
+ item = state.items;
+ while(item && item->type == IT_LITERAL)
+ {
+buf_append(&state.parser, "// TODO: eat %s\n\n", item->name);
+ item = item->next;
+ }
+ buf_append(&state.parser, "\t/* SET */\n");
+buf_append(&state.parser, "// TODO: SET\n");
+ break;
+
+ case ASN1TYPE_SEQUENCE:
+ /* assert */
+ if(!state.and_items)
+ fatal("SEQUENCE type, but and_items not set");
+ buf_append(&state.parser, "\t/* SEQUENCE */\n");
+ buf_append(&state.parser, "\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);
+ if(item->type == IT_LITERAL)
+ {
+buf_append(&state.parser, "// 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);
+ if(item->type != IT_OPTIONAL)
+ {
+ buf_append(&state.parser, "\telse\n");
+ buf_append(&state.parser, "\t\tparse_error(\"Expecting %s\");\n", item->name);
+ }
+ }
+ }
+ break;
+
+ default:
+ fatal("Illegal ASN1TYPE");
+ break;
+ }
+ }
+ buf_append(&state.parser, "}\n\n", name);
+
/* free the items */
item = state.items;
while(item)
@@ -556,3 +719,4 @@
return;
}
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|