unoidl2

Unnamed repository; edit this file to name it for gitweb.
git clone https://logand.com/git/unoidl2.git/
Log | Files | Refs

commit a9e6990b9520b08203b743e9eac76ee1e1f66f63
Author: Tomas Hlavaty <tom@logand.com>
Date:   Wed, 30 Nov 2011 23:52:04 +0100

initial commit

Diffstat:
AMakefile | 22++++++++++++++++++++++
Aparse.y | 159+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ascan.ll | 127+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aunoidl2.c | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aunoidl2.h | 15+++++++++++++++
Aunoidl2ast.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; +}