commit a9e6990b9520b08203b743e9eac76ee1e1f66f63
Author: Tomas Hlavaty <tom@logand.com>
Date: Wed, 30 Nov 2011 23:52:04 +0100
initial commit
Diffstat:
A | Makefile | | | 22 | ++++++++++++++++++++++ |
A | parse.y | | | 159 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | scan.ll | | | 127 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | unoidl2.c | | | 89 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | unoidl2.h | | | 15 | +++++++++++++++ |
A | unoidl2ast.c | | | 15 | +++++++++++++++ |
6 files changed, 427 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -0,0 +1,22 @@
+CFLAGS=-std=c99
+
+ALL=unoidl2ast
+
+all: $(ALL)
+
+scan.c: parse.c.h scan.ll
+ flex -o$@ scan.ll
+
+parse.c.h: parse.c
+
+parse.c: parse.y
+ bison --defines=$@.h -o$@ $<
+
+unoidl2.c: parse.o
+unoidl2ast.o: parse.o
+
+unoidl2ast: unoidl2ast.o unoidl2.o scan.o parse.o
+ $(CC) -o$@ $< unoidl2.o scan.o parse.o
+
+clean:
+ rm -rf $(ALL) scan.c parse.c.h parse.c *.o
diff --git a/parse.y b/parse.y
@@ -0,0 +1,159 @@
+%{
+#include "unoidl2.h"
+
+#include <stdio.h>
+#include <string.h>
+
+void yyerror(const char *str)
+{
+ fprintf(stderr,"error: %s\n",str);
+}
+
+int yywrap()
+{
+ return 1;
+}
+
+extern int yylex(void);
+
+Any ast;
+
+%}
+
+%union {
+ Any a;
+}
+
+%token<a> TRUE FALSE ID BOOL INT FLOAT EQ LT LE GT GE PLUS MINUS MUL DIV MOD
+%token<a> OR XOR AND LSHIFT RSHIFT NOT SCOPE SEMICOLON
+%token<a> LPAR RPAR LSQUARE RSQUARE LCURLY RCURLY COMMA COLON
+
+%token<a> ATTRIBUTE BOUND CASE CONST CONSTANTS CONSTRAINED DEFAULT ENUM
+%token<a> EXCEPTION INTERFACE MAYBEAMBIGUOUS MAYBEDEFAULT MAYBEVOID MODULE
+%token<a> NEEDS OBSERVES OPTIONAL PROPERTY RAISES READONLY REMOVEABLE SERVICE
+%token<a> SEQUENCE SINGLETON STRUCT SWITCH TRANSIENT TYPEDEF UNION ANY BOOLEAN
+%token<a> BYTE CHAR DOUBLE HYPER LONG SHORT STRING TYPE UNSIGNED VOID IN
+%token<a> OUT INOUT ONEWAY GET SET PUBLISHED ELLIPSIS FLOATING_PT_LITERAL
+
+%type<a> exp xor_exp and_exp shift_exp add_exp mul_exp unary_exp primary_exp
+%type<a> shift_op add_op mul_op unary_op name relname literal identifier
+
+%%
+
+/* idl_specification: nil | declaration; */
+/* nil: {$$ = nil;}; */
+/* declaration: defenum | defstruct | deftemplate | defexception */
+/* | interface_forward_decl | definterface | deftype | constant_decl */
+/* | constants_decl | defmodule | interface_service_decl */
+/* | accumulated_service_decl | interface_singleton_decl */
+/* | service_singleton_decl; */
+/* published: nil | PUBLISHED {$$ = T;}; */
+/* defenum: published ENUM identifier LCURLY enum_members RCURLY SEMICOLON; */
+/* enum_members: enum_member {$$ = cons($1, NIL);} */
+/* | enum_member COMMA enum_members {$$ = cons($1, $2);}; */
+/* enum_member: identifier | identifier EQ exp {$$ = list3($2, $1, $3);}; */
+/* defstruct: published STRUCT identifier single_inheritance */
+/* LCURLY struct_members RCURLY SEMICOLON; */
+/* single_inheritance: nil | COLON name; */
+/* struct_members: struct_member | struct_member struct_members; */
+/* struct_member: type identifier SEMICOLON; */
+/* deftemplate: published STRUCT identifier struct_params */
+/* LCURLY template_members RCURLY SEMICOLON; */
+/* struct_params: LT identifiers GT; */
+/* identifiers: identifier {$$ = cons($1, NIL);} */
+/* | identifier COMMA identifiers {$$ = cons($1, $3)}; */
+/* template_members: template_member | template_member template_members; */
+/* template_member: struct_member_decl | parametric_member_decl; */
+/* parametric_member: identifier identifier SEMICOLON; */
+/* defexception: published EXCEPTION identifier single_inheritance LCURLY struct_members_opt RCURLY SEMICOLON; */
+/* struct_members_opt: nil | struct_members; */
+/* interface_forward_decl: published INTERFACE identifier SEMICOLON; */
+/* definterface: published INTERFACE identifier single_inheritance LCURLY interface_members_opt RCURLY SEMICOLON; */
+/* interface_member: interface_inheritance | attribute | defmethod; */
+/* interface_inheritance: optional INTERFACE name SEMICOLON {$$ = list2($3, $1);}; */
+/* optional: nil | LSQUARE OPTIONAL RSQUARE {$$ = $2;}; */
+
+/* attribute_decl: attribute_flags type identifier attribute_accesses_opt SEMICOLON; */
+/* attribute_accesses_opt: nil | LCURLY attribute_accesses RCURLY; */
+
+/* attribute_flags: LSQUARE (attribute_flag COMMA)* ATTRIBUTE (COMMA attribute_flag)* RSQUARE */
+
+/* attribute_flag: BOUNG | READONLY; */
+/* attribute_access_decl: attribute_get | attribute_set; */
+/* attribute_get: GET exception_spec SEMICOLON; */
+/* attribute_set: SET exception_spec SEMICOLON; */
+
+/* exception_spec: RAISES LPAR name (COMMA name)* RPAR */
+
+/* method_decl: [LSQUARE ONEWAY RSQUARE] [type] identifier LPAR [method_param (COMMA method_param)*] RPAR [exception_spec] SEMICOLON */
+
+/* method_param: LSQUARE direction RSQUARE type identifier; */
+
+/* direction: IN | OUT | INOUT; */
+
+/* deftype: published TYPEDEF type identifier SEMICOLON; */
+
+/* constant_decl: published const_decl; */
+
+/* const_decl: CONST type identifier EQ exp SEMICOLON; */
+
+/* constants_decl: published CONSTANTS identifier LCURLY const_decl* RCURLY SEMICOLON; */
+
+/* defmodule: MODULE identifier LCURLY declaration* RCURLY SEMICOLON */
+
+/* interface_service_decl: published SERVICE identifier [COLON name] [LCURLY constructor_decl* RCURLY] SEMICOLON */
+
+/* constructor_decl: identifier LPAR [constructor_params] RPAR [exception_spec] SEMICOLON */
+
+/* constructor_params: rest_param | ctor_param (COMMA ctor_param)* */
+
+/* rest_param: LSQUARE IN RSQUARE ANY "..." identifier */
+
+/* ctor_param: LSQUARE IN RSQUARE type identifier */
+
+/* accumulated_service_decl: published SERVICE identifier [COLON name"]{" service_member_decl+ RCURLY SEMICOLON */
+
+/* service_member_decl: service_inheritance_decl | interface_inheritance_decl | property_decl */
+
+/* service_inheritance_decl: [LSQUARE OPTIONAL RSQUARE] SERVICE name SEMICOLON */
+
+/* property_decl: property_flags type identifier SEMICOLON; */
+
+/* property_flags: LSQUARE (property_flag COMMA)* PROPERTY (COMMA property_flag)* RSQUARE */
+
+/* property_flag: BOUND | CONSTRAINED | MAYBEAMBIGUOUS | MAYBEDEFAULT | MAYBEVOID | OPTIONAL | READONLY | REMOVABLE | TRANSIENT */
+
+/* interface_singleton_decl: published SINGLETON identifier COLON name SEMICOLON */
+
+/* service_singleton_decl: published SINGLETON identifier LCURLY SERVICE name SEMICOLON RCURLY SEMICOLON */
+
+
+/* type: simple_type | sequence_type | template_type | name; */
+/* simple_type: VOID | BOOLEAN | BYTE | SHORT | UNSIGNED SHORT | LONG */
+/* | UNSIGNED LONG | HYPER | UNSIGNED HYPER | FLOAT | DOUBLE | CHAR */
+/* | STRING | TYPE | ANY; */
+/* sequence_type: SEQUENCE LT type GT; */
+
+/* template_type: name LT type GT | (COMMA type)* ">" */
+
+
+
+ast: exp {ast = $1};
+exp: xor_exp | exp OR xor_exp {$$ = list3($2, $1, $3);};
+xor_exp: and_exp | xor_exp XOR and_exp {$$ = list3($2, $1, $3);};
+and_exp: shift_exp | and_exp AND shift_exp {$$ = list3($2, $1, $3);};
+shift_exp: add_exp | shift_exp shift_op add_exp {$$ = list3($2, $1, $3);};
+shift_op: LSHIFT | RSHIFT;
+add_exp: mul_exp | add_exp add_op mul_exp {$$ = list3($2, $1, $3);};
+add_op: PLUS | MINUS;
+mul_exp: unary_exp | mul_exp mul_op unary_exp {$$ = list3($2, $1, $3);};
+mul_op: MUL | DIV | MOD;
+unary_exp: primary_exp | unary_op primary_exp {$$ = list2($1, $2);};
+unary_op: PLUS | MINUS | NOT;
+primary_exp: name | literal | '(' exp ')' {$$ = $2;};
+literal: BOOL | INT | FLOAT;
+name: relname | SCOPE relname {$$ = list2($1, $2);};
+relname: identifier | identifier SCOPE relname {$$ = list2($1, $3);};
+identifier: ID
+
+%%
diff --git a/scan.ll b/scan.ll
@@ -0,0 +1,127 @@
+%{
+#include "unoidl2.h"
+#include "parse.c.h"
+#include <stdio.h>
+//#include <string.h>
+
+char *strdup(char *);
+
+int yycolumn = 1;
+
+enum yytokentype tok(enum yytokentype kind, char *token) {
+ printf("{%s}\n", token);
+ yylval.a = mk(kind, token);
+ return kind;
+}
+%}
+
+%option noyywrap
+%option never-interactive
+
+DIGIT [0-9]
+OCT_DIGIT [0-7]
+HEX_DIGIT [a-fA-F0-9]
+CAPITAL [A-Z]
+ALPHA [a-zA-Z]
+INT [1-9][0-9]*
+OCT 0{OCT_DIGIT}*
+HEX (0x|0X){HEX_DIGIT}*
+
+IDENTIFIER_NEW ({ALPHA}({ALPHA}|{DIGIT})*)|({CAPITAL}("_"?({ALPHA}|{DIGIT})+)*)
+IDENTIFIER ("_"?({ALPHA}|{DIGIT})+)*
+
+%%
+[ \t\r]+ ; /* eat up whitespace */
+[\n] {
+ yycolumn = 1;
+ yylineno++;
+}
+
+"=" return tok(EQ, "=");
+"<" return tok(LT, "<");
+"<=" return tok(LE, "<=");
+">" return tok(GT, ">");
+">=" return tok(GE, ">=");
+"+" return tok(PLUS, "+");
+"-" return tok(MINUS, "-");
+"*" return tok(MUL, "*");
+"/" return tok(DIV, "/");
+"%" return tok(MOD, "%");
+"|" return tok(OR, "|");
+"^" return tok(XOR, "^");
+"&" return tok(AND, "&");
+"<<" return tok(LSHIFT, "<<");
+">>" return tok(RSHIFT, ">>");
+"~" return tok(NOT, "~");
+"::" return tok(SCOPE, "::");
+
+attribute return tok(ATTRIBUTE, "attribute");
+bound return tok(BOUND, "bound");
+case return tok(CASE, "case");
+const return tok(CONST, "const");
+constants return tok(CONSTANTS, "constants");
+constrained return tok(CONSTRAINED, "constrained");
+default return tok(DEFAULT, "default");
+enum return tok(ENUM, "enum");
+exception return tok(EXCEPTION, "exception");
+interface return tok(INTERFACE, "interface");
+maybeambiguous return tok(MAYBEAMBIGUOUS, "maybeambiguous");
+maybedefault return tok(MAYBEDEFAULT, "maybedefault");
+maybevoid return tok(MAYBEVOID, "maybevoid");
+module return tok(MODULE, "module");
+needs return tok(NEEDS, "needs");
+observes return tok(OBSERVES, "observes");
+optional return tok(OPTIONAL, "optional");
+property return tok(PROPERTY, "property");
+raises return tok(RAISES, "raises");
+readonly return tok(READONLY, "readonly");
+removable return tok(REMOVEABLE, "removable");
+service return tok(SERVICE, "service");
+sequence return tok(SEQUENCE, "sequence");
+singleton return tok(SINGLETON, "singleton");
+struct return tok(STRUCT, "struct");
+switch return tok(SWITCH, "switch");
+transient return tok(TRANSIENT, "transient");
+typedef return tok(TYPEDEF, "typedef");
+union return tok(UNION, "union");
+
+any return tok(ANY, "any");
+boolean return tok(BOOLEAN, "boolean");
+byte return tok(BYTE, "byte");
+char return tok(CHAR, "char");
+double return tok(DOUBLE, "double");
+float return tok(FLOAT, "float");
+hyper return tok(HYPER, "hyper");
+long return tok(LONG, "long");
+short return tok(SHORT, "short");
+string return tok(STRING, "string");
+type return tok(TYPE, "type");
+unsigned return tok(UNSIGNED, "unsigned");
+void return tok(VOID, "void");
+
+TRUE return tok(TRUE, "true");
+True return tok(TRUE, "true");
+FALSE return tok(FALSE, "false");
+False return tok(FALSE, "false");
+
+in return tok(IN, "in");
+out return tok(OUT, "out");
+inout return tok(INOUT, "inout");
+oneway return tok(ONEWAY, "oneway");
+
+get return tok(GET, "get");
+set return tok(SET, "set");
+
+published return tok(PUBLISHED, "published");
+
+"..." return tok(ELLIPSIS, "ellipsis");
+
+"//"[^/]{1}.*"\n" {yylineno++;}
+
+"///".*"\n" {yylineno++;}
+
+{DIGIT}+ return tok(INT, strdup(yytext));
+
+. return yytext[0];
+
+%%
diff --git a/unoidl2.c b/unoidl2.c
@@ -0,0 +1,89 @@
+#include "unoidl2.h"
+#include "parse.c.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+struct any {
+ enum {CONS, TOKEN} tag;
+ union {
+ struct {
+ struct any *car;
+ struct any *cdr;
+ } c;
+ struct {
+ Kind kind;
+ char *token;
+ } t;
+ } u;
+};
+
+static const Any NIL = NULL;
+static struct any _T = {.tag = CONS, .u = {.t = {.kind = 0, .token = "T"}}};
+static const Any T = &_T;
+
+Any cons(Any car, Any cdr) {
+ Any x = malloc(sizeof(struct any));
+ x->tag = CONS;
+ x->u.c.car = car;
+ x->u.c.cdr = cdr;
+ return x;
+}
+
+Any mk(Kind kind, char *token) {
+ Any x = malloc(sizeof(struct any));
+ x->tag = TOKEN;
+ x->u.t.kind = kind;
+ x->u.t.token = token;
+ return x;
+}
+
+Any consp(Any x) {
+ return CONS == x->tag ? T : NIL;
+}
+
+Any car(Any x) {
+ return x->u.c.car;
+}
+
+Any cdr(Any x) {
+ return x->u.c.cdr;
+}
+
+Any list1(Any a)
+{
+ return cons(a, NIL);
+}
+
+Any list2(Any a, Any b)
+{
+ return cons(a, cons(b, NIL));
+}
+
+Any list3(Any a, Any b, Any c)
+{
+ return cons(a, cons(b, cons(c, NIL)));
+}
+
+void print(Any x) {
+ if(x) {
+ if(consp(x)) {
+ printf("(");
+ print(car(x));
+ Any d;
+ for(d = cdr(x); d; d = cdr(d)) {
+ printf(" ");
+ if(consp(d))
+ print(car(d));
+ else {
+ printf(". ");
+ print(d);
+ break;
+ }
+ }
+ printf(")");
+ } else
+ printf("%s", x->u.t.token);
+ } else
+ printf("NIL");
+}
diff --git a/unoidl2.h b/unoidl2.h
@@ -0,0 +1,15 @@
+struct any;
+typedef struct any *Any;
+
+enum yytokentype;
+typedef enum yytokentype Kind;
+
+Any cons(Any car, Any cdr);
+Any mk(Kind kind, char *token);
+Any consp(Any x);
+Any car(Any x);
+Any cdr(Any x);
+Any list1(Any a);
+Any list2(Any a, Any b);
+Any list3(Any a, Any b, Any c);
+void print(Any x);
diff --git a/unoidl2ast.c b/unoidl2ast.c
@@ -0,0 +1,15 @@
+#include "unoidl2.h"
+#include "parse.c.h"
+
+#include <stdio.h>
+
+extern int yyparse();
+
+extern Any ast;
+
+int main() {
+ yyparse();
+ print(ast);
+ printf("\n");
+ return 0;
+}