From 82f47550fe3327cce6f2e0e1bf62e81d9ebcf90c Mon Sep 17 00:00:00 2001 From: sanine Date: Wed, 18 Jan 2023 13:03:34 -0600 Subject: begin reentrant refactor --- yy/in.xml | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yy/kalmia.h | 2 + yy/kalmia.l | 92 +++++++++++++++++++++++++++++++------------- yy/kalmia.y | 71 +++++++++++++--------------------- yy/main.c | 22 +++++++++++ yy/makefile | 15 +++++--- 6 files changed, 250 insertions(+), 78 deletions(-) create mode 100644 yy/in.xml create mode 100644 yy/kalmia.h create mode 100644 yy/main.c (limited to 'yy') diff --git a/yy/in.xml b/yy/in.xml new file mode 100644 index 0000000..ddd1543 --- /dev/null +++ b/yy/in.xml @@ -0,0 +1,126 @@ + + + + 2005-11-14T02:16:38Z + 2005-11-15T11:36:38Z + 1.0 + + + + + + + + 1.0 1.0 1.0 1.0 + + + 1.0 1.0 1.0 1.0 + + + 1.0 1.0 1.0 1.0 + + + 1.0 1.0 1.0 1.0 + + + 20.0 + + + 1.0 1.0 1.0 1.0 + + + 0.5 + + + 1.0 1.0 1.0 1.0 + + + 1.0 + + + + + + + + + + + + + + + + + -0.5 0.5 0.5 + 0.5 0.5 0.5 + -0.5 -0.5 0.5 + 0.5 -0.5 0.5 + -0.5 0.5 -0.5 + 0.5 0.5 -0.5 + -0.5 -0.5 -0.5 + 0.5 -0.5 -0.5 + + + + + + + + + + + + 1.0 0.0 0.0 + -1.0 0.0 0.0 + 0.0 1.0 0.0 + 0.0 -1.0 0.0 + 0.0 0.0 1.0 + 0.0 0.0 -1.0 + + + + + + + + + + + + + + + +

0 4 2 4 3 4 1 4

+

0 2 1 2 5 2 4 2

+

6 3 7 3 3 3 2 3

+

0 1 4 1 6 1 2 1

+

3 0 7 0 5 0 1 0

+

5 5 7 5 6 5 4 5

+
+
+
+
+ + + + 0 0 0 + 0 0 1 0 + 0 1 0 0 + 1 0 0 0 + 1 1 1 + + + + + + + + + + + + + +
diff --git a/yy/kalmia.h b/yy/kalmia.h new file mode 100644 index 0000000..6259956 --- /dev/null +++ b/yy/kalmia.h @@ -0,0 +1,2 @@ +#include "kalmia.tab.h" +#include "kalmia.lex.h" diff --git a/yy/kalmia.l b/yy/kalmia.l index 2472bdc..916f576 100644 --- a/yy/kalmia.l +++ b/yy/kalmia.l @@ -1,26 +1,39 @@ -%{ -#include -#include "y.tab.h" - -char *copy_str(char *); -int line_num; +%option noinput nounput noyywrap 8bit nodefault +%option reentrant bison-bridge bison-locations +%start STRING +%{ +#include +#include "kalmia.tab.h" +#define YY_USER_ACTION \ + yylloc->first_line = yylloc->last_line; \ + yylloc->first_column = yylloc->last_column; \ + if (*yytext == '\n') { \ + yylloc->last_line += 1; \ + yylloc->last_column = 0; \ + } \ + else { \ + yylloc->last_column += yyleng; \ + } %} S \x20\x0a\x0d\x09 DATE [0-9]{4}\-[0-9]{2}\-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}[A-Z]* +ATTR ([\x20\x0a\x0d\x09]*)?"=" - -%start STRING - %% -"" { return PROLOG; } -[\x20\x0a\x0d\x09] { if (*yytext == '\n') { line_num += 1; } } +"" { + /* xml prologue */ + return PROLOG; +} +[\x20\x0a\x0d\x09] { + /* ignore whitespace */ +} "<" { return S_TAG_OPEN; } @@ -29,24 +42,49 @@ DATE [0-9]{4}\-[0-9]{2}\-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}[A-Z]* "/>" { return EMPTY_TAG_CLOSE; } -[a-zA-Z_:][a-zA-Z0-9\.\-_:]* { yylval.sval = copy_str(yytext); return NAME; } - -"=" { return *yytext; } +[a-zA-Z_:][a-zA-Z0-9\.\-_:]* { + /* generic tag name */ + yylval->sval = strdup(yytext); return NAME; +} +[a-zA-Z_:][a-zA-Z0-9\.\-_:]*/([\x20\x0a\x0d\x09])*"=" { + /* generic attribute key */ + yylval->sval = strdup(yytext); + return ATTR; +} +"=" { + /* attribute "=" */ + return *yytext; +} -"\"" { BEGIN(STRING); return *yytext; } -"\"" { BEGIN(INITIAL); return *yytext; } -[^"] { yylval.cval = *yytext; return CHAR; } --?[0-9]+ { yylval.lval = strtol(yytext, NULL, 10); return INTEGER; } --?[0-9]+\.?[0-9]* { yylval.dval = strtod(yytext, NULL); return DOUBLE; } -{DATE} { return DATE; } +"\"" { + /* begin a string */ + BEGIN(STRING); + return *yytext; +} +"\"" { + /* end a string */ + BEGIN(INITIAL); + return *yytext; +} +[^"]+ { + /* within a string */ + yylval->sval = strdup(yytext); + return TEXT; +} -%% -char * copy_str(char *str) -{ - size_t len = strlen(str) + 1; - char *copy = malloc(sizeof(char) * len); - strncpy(copy, str, len); - return copy; +-?[0-9]+ { + /* integers */ + yylval->lval = strtol(yytext, NULL, 10); + return INTEGER; +} +-?[0-9]+\.?[0-9]* { + /* doubles */ + yylval->dval = strtod(yytext, NULL); + return DOUBLE; +} +{DATE} { + /* dates */ + return DATE; } diff --git a/yy/kalmia.y b/yy/kalmia.y index 5d808e2..8afc101 100644 --- a/yy/kalmia.y +++ b/yy/kalmia.y @@ -1,12 +1,18 @@ -%{ -#include -int yyerror(const char *); -int yylex(); - -char attr_buf[1024]; -int attr_i; -%} +%define api.pure full +%locations +%define parse.error verbose +%param { yyscan_t scanner } +%code top { + #include +} +%code requires { + typedef void* yyscan_t; +} +%code { + int yylex(YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t scanner); + int yyerror(YYLTYPE *yyllocp, yyscan_t unused, const char *msg); +} %union { long lval; @@ -18,15 +24,13 @@ int attr_i; %token PROLOG %token S_TAG_OPEN E_TAG_OPEN TAG_CLOSE EMPTY_TAG_CLOSE %token NAME -%token CHAR +%token ATTR +%token TEXT %token INTEGER %token DOUBLE %token DATE; -%define parse.error verbose - - %% @@ -68,51 +72,28 @@ attributes: ; attribute: - NAME '=' '"' chars '"' { attr_buf[attr_i] = 0; printf("attribute: %s=%s\n", $1, attr_buf); attr_i = 0; } - ; - -chars: - | CHAR { attr_buf[attr_i] = $1; attr_i += 1; } - | chars CHAR { attr_buf[attr_i] = $2; attr_i += 1; } + ATTR '=' '"' TEXT '"' { printf("attribute: %s=%s\n", $1, $4); } ; integers: - INTEGER - | integers INTEGER + INTEGER { printf("%d\n", $1); } + | integers INTEGER { printf("%d\n", $2); } ; doubles: - DOUBLE - | doubles DOUBLE + DOUBLE { printf("%f\n", $1); } + | doubles DOUBLE { printf("%f\n", $2); } ; %% - -extern FILE *yyin; -extern int line_num; - -int main() -{ - attr_i = 0; - line_num = 0; - yyin = fopen("in.xml", "r"); - if (yyin == NULL) { - fprintf(stderr, "could not open file!\n"); - return -1; - } - do { - yyparse(); - } while (!feof(yyin)); - - return 0; -} - - -int yyerror(const char *msg) +int yyerror(YYLTYPE *yyllocp, yyscan_t unused, const char *msg); { - fprintf(stderr, "parse error on line %d: %s\n", line_num, msg); + fprintf( + stderr, "[%d:%d]: %s\n", + yyllocp->first_line, yyllocp->first_column, msg + ); return 1; } diff --git a/yy/main.c b/yy/main.c new file mode 100644 index 0000000..d53a598 --- /dev/null +++ b/yy/main.c @@ -0,0 +1,22 @@ +#include +#include "kalmia.h" + +int main(int argc, char **argv) +{ + if (argc < 2) { + fprintf(stderr, "You must specify a file to parse!\n"); + return -1; + } + FILE *in = fopen(argv[1], "r"); + if (in == NULL) { + fprintf(stderr, "Could not open file \"%s\"\n", argv[1]); + return -1; + } + + yyscan_t scanner; + yylex_init(&scanner); + yyset_in(in, scanner); + yyparse(scanner); + yylex_destroy(scanner); + return 0; +} diff --git a/yy/makefile b/yy/makefile index cd482dc..5f33c4f 100644 --- a/yy/makefile +++ b/yy/makefile @@ -1,10 +1,13 @@ all: kalmia -y.tab.c: kalmia.y - yacc -d kalmia.y +kalmia.tab.c: kalmia.y + bison -o "$@" --header=kalmia.tab.h kalmia.y -lex.yy.c: kalmia.l - lex kalmia.l +kalmia.lex.c: kalmia.l + flex -o "$@" --header-file "kalmia.lex.h" kalmia.l -kalmia: y.tab.c lex.yy.c - gcc -o kalmia y.tab.c lex.yy.c -lfl +kalmia: kalmia.tab.c kalmia.lex.c main.c kalmia.h + gcc -o kalmia main.c kalmia.tab.c kalmia.lex.c -lfl + +clean: + rm kalmia.lex.c kalmia.lex.h kalmia.tab.c kalmia.tab.h kalmia -- cgit v1.2.1