From e0a3adb33b0941e07403ca62b4413e52db8794ba Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Tue, 7 Feb 2012 00:23:37 +0400 Subject: [PATCH] first commit --- cparse.h | 97 ++++++++++++++++++++++++++++++++++++++++++ cparse.l | 112 ++++++++++++++++++++++++++++++++++++++++++++++++ cparse.y | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++ parser.sh | 4 ++ struct.c | 7 +++ test_parser.c | 17 ++++++++ 6 files changed, 352 insertions(+) create mode 100644 cparse.h create mode 100644 cparse.l create mode 100644 cparse.y create mode 100755 parser.sh create mode 100644 struct.c create mode 100644 test_parser.c diff --git a/cparse.h b/cparse.h new file mode 100644 index 0000000..a400787 --- /dev/null +++ b/cparse.h @@ -0,0 +1,97 @@ +// TODO: add kernel like (uint8_t) types support + +/* ====================== Tokens ===================== */ + +#define IDENTIFIER 1 +#define TYPE_CHAR 10 +#define TYPE_SHORT 11 +#define TYPE_INT 12 +#define TYPE_LONG 13 +#define BRACKET_LQUADRATIC 22 +#define BRACKET_RQUADRATIC 23 +#define BRACKET_LFIGURE 24 +#define BRACKET_RFIGURE 25 +#define COMPLEX_STRUCT 30 +#define COMPLEX_UNION 31 + +struct token { + char* name; + char* value; + int type; +}; + +typedef struct token_lst token_list; +struct token_lst { + struct token *tok; + token_list *next; + token_list *prev; + token_list *head; +}; + +/* ==================== Lexems ====================== */ + +#define ITEM_STRUCT 1 +#define ITEM_ARRAY 2 +#define ITEM_POINTER 3 +#define ITEM_VARIABLE 4 + +struct item_variable { + char* name; + int type; + int size; + union { + short shrt; + int intgr; + long lng; + char chr; + } value; +}; + +struct item_pointer { + char* name; + int type; + int size; + union { + short shrt; + int intgr; + long lng; + char chr; + } value; +}; + +struct item_array { + char* name; + int type; + long size; + long count; + union { + short shrt; + int intgr; + long lng; + char chr; + } value; +}; + +typedef struct item_lst item_list; + +struct item_struct { + char* name; + long size; + int level; + item_list *items; +}; + +struct item_lst { + short item_type; + union { + struct item_variable *var; + struct item_pointer *ptr; + struct item_array *arr; + struct item_struct *str; + } item; + item_list *next; + item_list *prev; + item_list *head; +}; + + diff --git a/cparse.l b/cparse.l new file mode 100644 index 0000000..e428fd3 --- /dev/null +++ b/cparse.l @@ -0,0 +1,112 @@ +%{ +#include +#include +#define YYSTYPE char* +#define YYDECL int yylex( YYSTYPE * yylval, yyscan_t yyscanner) +#define YYLEX_PARAM yyscanner +#include "cparse.tab.h" +#include "cparse.h" + +%} + +digits [0-9]* +letters [a-zA-Z]* +validid [a-zA-Z_][a-zA-Z0-9]+ + +%% +"/*" { return(COMMENT_START); } +"*/" { return(COMMENT_END); } + +"void" { count(); return(VOID); } +"char" { count(); return(CHAR); } +"int" { count(); return(INT); } +"long" { count(); return(LONG); } +"short" { count(); return(SHORT); } +"float" { count(); return(FLOAT); } +"double" { count(); return(DOUBLE); } +"const" { count(); return(CONST); } +"register" { count(); return(REGISTER); } +"signed" { count(); return(SIGNED); } +"unsigned" { count(); return(UNSIGNED); } +"static" { count(); return(STATIC); } +"volatile" { count(); return(VOLATILE); } +"enum" { count(); return(ENUM); } +"struct" { count(); return(STRUCT); } +"union" { count(); return(UNION); } + +"{" { count(); return(OBRACE); } +"}" { count(); return(EBRACE); } +"[" { count(); return(LBRACKET); } +"]" { count(); return(RBRACKET); } +";" { count(); return(SEMICOLON); } + +[ \t\v\n\f] { count(); } +validid { count(); return(IDENTIFIER); } +digits { count(); return(NUMBER); } +. { /* ignore bad characters */ } + +%% + +yywrap() { + return(1); +} + + +comment() { + char c, c1; + +loop: + while ((c = input()) != '*' && c != 0) + putchar(c); + + if ((c1 = input()) != '/' && c != 0) + { + unput(c1); + goto loop; + } + + if (c != 0) + putchar(c1); +} + + +int column = 0; + +void count() { + int i; + + for (i = 0; yytext[i] != '\0'; i++) + if (yytext[i] == '\n') + column = 0; + else if (yytext[i] == '\t') + column += 8 - (column % 8); + else + column++; +} + +int check_type() { +/* + if (yytext == type_name) + return(TYPE_NAME); + else +*/ + return(IDENTIFIER); +} + + +int main(int argc, char** argv) { + char *programname; + char *cfile; + if (argc == 2) { + programname = argv[0]; + cfile = argv[1]; + yyin = fopen(cfile, "r"); + printf("Opened file %s for parsing!\n", cfile); + yylex(); + printf("Parsing done!\n"); + } else { + printf("Error! I need c program to parse!\n"); + return -1; + } + return 0; +} diff --git a/cparse.y b/cparse.y new file mode 100644 index 0000000..16a87c4 --- /dev/null +++ b/cparse.y @@ -0,0 +1,115 @@ +%{ +#include +#define YYSTYPE char* +#define YYDECL int yylex( YYSTYPE * yylval, yyscan_t yyscanner) +#define YYLEX_PARAM yyscanner +#include "cparse.h" + +%} + +%parse-param { yyscan_t yyscanner } + +%token COMMENT_START COMMENT_END +%token STRUCT UNION ENUM +%token CHAR SHORT INT LONG FLOAT DOUBLE VOID +%token SIGNED UNSIGNED +%token STATIC CONST REGISTER VOLATILE +%token NUMBER STRING IDENTIFIER +%token OBRACE EBRACE LBRACKET RBRACKET SEMICOLON ASTERISK + +%% + +defs: + | defs def + ; + +def: + | st + | un + | en + | var + ; + +st: + | STRUCT name OBRACE defs EBRACE SEMICOLON + { + printf("Found struct %s\n", $2); + } + ; + +un: + | UNION name OBRACE defs EBRACE SEMICOLON + { + printf("Found union %s\n", $2); + } + ; + +en: + | ENUM name OBRACE names EBRACE SEMICOLON + ; + +var: + | modifier signedness type name SEMICOLON + { + printf("Found %s variable of %s type\n", $4, $3); + } + | modifier signedness type ASTERISK name SEMICOLON + { + printf("Found %s pointer of %s type\n", $5, $3); + } + | modifier signedness type name LBRACKET size RBRACKET SEMICOLON + { + printf("Found %s array of %s type with size %ld\n", $4, $3, $6); + } + ; + +size: + | NUMBER + ; + +constant: + | NUMBER + | STRING + ; + +type: + | CHAR + | SHORT + | INT + | LONG + | LONG LONG + | FLOAT + | DOUBLE + | VOID + ; + +signedness: + | SIGNED + | UNSIGNED + ; + +modifier: + | STATIC + | CONST + | REGISTER + | VOLATILE + ; + +name: + | IDENTIFIER + ; + +names: + | names name + ; + +%% + +int main(void) +{ + yyscan_t scanner; + yylex_init(&scanner); + yyset_in(stdin, scanner); + while (yyparse( scanner)); + yylex_destroy(scanner); +} diff --git a/parser.sh b/parser.sh new file mode 100755 index 0000000..885bf2f --- /dev/null +++ b/parser.sh @@ -0,0 +1,4 @@ +#!/bin/sh +bison -d cparse.y +flex cparse.l +gcc -o cparse lex.yy.c -lfl -lm diff --git a/struct.c b/struct.c new file mode 100644 index 0000000..24dc101 --- /dev/null +++ b/struct.c @@ -0,0 +1,7 @@ +struct qwe { + int y; + long long m; + char *x; + char cmdbuf[256]; + char g; +}; diff --git a/test_parser.c b/test_parser.c new file mode 100644 index 0000000..a77a90a --- /dev/null +++ b/test_parser.c @@ -0,0 +1,17 @@ +struct highlight { + int hex_start; + int hex_end; + int dat_start; + int dat_end; + struct qwe2 { + int linux; + char *qwe; + char* lst; + long zied[15]; + }; + int flg; + int palette; + long qwe; + int toggle; +}; +