From 3519c014e86f5ce651f196a4abb584404b24a10f Mon Sep 17 00:00:00 2001 From: overflowerror Date: Thu, 20 May 2021 18:02:42 +0200 Subject: [PATCH] lexer and parser seem to work now --- src/main.c | 13 +++++++++++++ src/parser.y | 26 +++++++++++++++++--------- src/scanner.l | 32 ++++++++++++++++++-------------- 3 files changed, 48 insertions(+), 23 deletions(-) create mode 100644 src/main.c diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..a31561d --- /dev/null +++ b/src/main.c @@ -0,0 +1,13 @@ + +#include + +extern int yyparse(); + +int main() { + return yyparse(); +} + +void yyerror(char* s) { + extern int yylineno; + fprintf(stderr, "%s (line %d)\n", s, yylineno); +} diff --git a/src/parser.y b/src/parser.y index 2a0fd71..0ac7248 100644 --- a/src/parser.y +++ b/src/parser.y @@ -1,4 +1,12 @@ +%{ + +int yylex(); + +extern void yyerror(char*); + +%} + %token SECTION TEXT COMMA END %token PARAMS_BEGIN PARAMS_END %token STATEMENT_BEGIN STATEMENT_END @@ -11,20 +19,19 @@ file: metaSection SECTION mainSection ; -metaSection: PARAMS_BEGIN parameters PARAMS_END - | STATEMENT_BEGIN metaStatement STATEMENT_END +metaSection: /* empty */ + | PARAMS_BEGIN parameters PARAMS_END metaSection + | STATEMENT_BEGIN metaStatement STATEMENT_END metaSection ; parameters: /* empty */ | parameter moreParameters ; -parameter: /* empty */ - | TEXT parameter +parameter: TEXT texts ; moreParameters: /* empty */ - | COMMA /* allow trailing commas */ | COMMA parameter moreParameters ; @@ -40,10 +47,11 @@ mainSection: /* empty */ blockStatement: statement ; -statement: TEXT /* statement can't be empty */ - | TEXT statement +statement: TEXT texts ; -output: TEXT /* output can't be empty */ - | TEXT output +output: TEXT texts ; + +texts: /* empty */ + | TEXT texts diff --git a/src/scanner.l b/src/scanner.l index 4bc6adc..56121c4 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -11,7 +11,8 @@ statement_end "%}" output_begin "{{" output_end "}}" -block_end "end" +block_end_token "end" +block_end {whitespace}*{block_end_token}{whitespace}* type_prefixes "enum"|"struct" type_prefix {type_prefixes}{whitespace}+ @@ -19,18 +20,16 @@ type_pointer {whitespace}*"*" type {type_prefix}?[a-zA-Z0-9_]+{type_pointer}? %option noyywrap -%option nodefault %option nounput %option noinput %option yylineno -%x PARAMS -%x STATEMENT -%x OUTPUT %x META_SECTION %x MAIN_SECTION -%s META_SECTION +%x PARAMS +%x STATEMENT +%x OUTPUT %% @@ -39,24 +38,29 @@ type {type_prefix}?[a-zA-Z0-9_]+{type_pointer}? #include #include + #include "y.tab.h" + bool isMetaSection = true; %} -{params_begin} { BEGIN(PARAMS); return PARAMS_BEGIN; } -{statement_begin} { BEGIN(STATEMENT); return STATEMENT_BEGIN; } -{section} { isMetaSection = false; BEGIN(MAIN_SECTION); } -{output_begin} { fprintf(stderr, "error: output block not allowed in meta section (line %d)\n", yylineno); exit(1); } -. { fprintf(stderr, "error: raw text not allowed in meta section (line %d)\n", yylineno); exit(1); } +{params_begin} { BEGIN(PARAMS); return PARAMS_BEGIN; } +{statement_begin} { BEGIN(STATEMENT); return STATEMENT_BEGIN; } +{section} { isMetaSection = false; BEGIN(MAIN_SECTION); return SECTION; } +{output_begin} { fprintf(stderr, "error: output block not allowed in meta section (line %d)\n", yylineno); exit(1); } +{whitespace}+ { /* ignore whitespaces */ } +. { fprintf(stderr, "error: raw text not allowed in meta section (line %d)\n", yylineno); exit(1); } {type} { return TEXT; } {params_end} { BEGIN(META_SECTION); return PARAMS_END; } "," { return COMMA; } {whitespace}+ { /* ignore whitespaces */ } -$ { return TEXT; /* catch $ as text */ } +"$" { return TEXT; /* catch $ as text */ } . { fprintf(stderr, "error: illegal token '%s' in parameter block (line %d)\n", yytext, yylineno); exit(1); } -[^%]+ { return TEXT; } -% { return TEXT; /* catch % as text */ } +[^%e]+ { return TEXT; } +{block_end} { return END; } +"%" { return TEXT; /* catch % as text */ } +"e" { return TEXT; /* catch e as text */ } {statement_end} { if (isMetaSection) BEGIN(META_SECTION); else BEGIN(MAIN_SECTION); return STATEMENT_END; } {params_begin} { fprintf(stderr, "warning: parameter block not allowed in main section (line %d); assuming to be text\n", yylineno); return TEXT; }