lexer and parser seem to work now

This commit is contained in:
overflowerror 2021-05-20 18:02:42 +02:00
parent 8b15908418
commit 3519c014e8
3 changed files with 48 additions and 23 deletions

13
src/main.c Normal file
View file

@ -0,0 +1,13 @@
#include <stdio.h>
extern int yyparse();
int main() {
return yyparse();
}
void yyerror(char* s) {
extern int yylineno;
fprintf(stderr, "%s (line %d)\n", s, yylineno);
}

View file

@ -1,4 +1,12 @@
%{
int yylex();
extern void yyerror(char*);
%}
%token SECTION TEXT COMMA END %token SECTION TEXT COMMA END
%token PARAMS_BEGIN PARAMS_END %token PARAMS_BEGIN PARAMS_END
%token STATEMENT_BEGIN STATEMENT_END %token STATEMENT_BEGIN STATEMENT_END
@ -11,20 +19,19 @@
file: metaSection SECTION mainSection file: metaSection SECTION mainSection
; ;
metaSection: PARAMS_BEGIN parameters PARAMS_END metaSection: /* empty */
| STATEMENT_BEGIN metaStatement STATEMENT_END | PARAMS_BEGIN parameters PARAMS_END metaSection
| STATEMENT_BEGIN metaStatement STATEMENT_END metaSection
; ;
parameters: /* empty */ parameters: /* empty */
| parameter moreParameters | parameter moreParameters
; ;
parameter: /* empty */ parameter: TEXT texts
| TEXT parameter
; ;
moreParameters: /* empty */ moreParameters: /* empty */
| COMMA /* allow trailing commas */
| COMMA parameter moreParameters | COMMA parameter moreParameters
; ;
@ -40,10 +47,11 @@ mainSection: /* empty */
blockStatement: statement blockStatement: statement
; ;
statement: TEXT /* statement can't be empty */ statement: TEXT texts
| TEXT statement
; ;
output: TEXT /* output can't be empty */ output: TEXT texts
| TEXT output
; ;
texts: /* empty */
| TEXT texts

View file

@ -11,7 +11,8 @@ statement_end "%}"
output_begin "{{" output_begin "{{"
output_end "}}" output_end "}}"
block_end "end" block_end_token "end"
block_end {whitespace}*{block_end_token}{whitespace}*
type_prefixes "enum"|"struct" type_prefixes "enum"|"struct"
type_prefix {type_prefixes}{whitespace}+ type_prefix {type_prefixes}{whitespace}+
@ -19,18 +20,16 @@ type_pointer {whitespace}*"*"
type {type_prefix}?[a-zA-Z0-9_]+{type_pointer}? type {type_prefix}?[a-zA-Z0-9_]+{type_pointer}?
%option noyywrap %option noyywrap
%option nodefault
%option nounput %option nounput
%option noinput %option noinput
%option yylineno %option yylineno
%x PARAMS
%x STATEMENT
%x OUTPUT
%x META_SECTION %x META_SECTION
%x MAIN_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 <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include "y.tab.h"
bool isMetaSection = true; bool isMetaSection = true;
%} %}
<META_SECTION>{params_begin} { BEGIN(PARAMS); return PARAMS_BEGIN; } <INITIAL,META_SECTION>{params_begin} { BEGIN(PARAMS); return PARAMS_BEGIN; }
<META_SECTION>{statement_begin} { BEGIN(STATEMENT); return STATEMENT_BEGIN; } <INITIAL,META_SECTION>{statement_begin} { BEGIN(STATEMENT); return STATEMENT_BEGIN; }
<META_SECTION>{section} { isMetaSection = false; BEGIN(MAIN_SECTION); } <INITIAL,META_SECTION>{section} { isMetaSection = false; BEGIN(MAIN_SECTION); return SECTION; }
<META_SECTION>{output_begin} { fprintf(stderr, "error: output block not allowed in meta section (line %d)\n", yylineno); exit(1); } <INITIAL,META_SECTION>{output_begin} { fprintf(stderr, "error: output block not allowed in meta section (line %d)\n", yylineno); exit(1); }
<META_SECTION>. { fprintf(stderr, "error: raw text not allowed in meta section (line %d)\n", yylineno); exit(1); } <INITIAL,META_SECTION>{whitespace}+ { /* ignore whitespaces */ }
<INITIAL,META_SECTION>. { fprintf(stderr, "error: raw text not allowed in meta section (line %d)\n", yylineno); exit(1); }
<PARAMS>{type} { return TEXT; } <PARAMS>{type} { return TEXT; }
<PARAMS>{params_end} { BEGIN(META_SECTION); return PARAMS_END; } <PARAMS>{params_end} { BEGIN(META_SECTION); return PARAMS_END; }
<PARAMS>"," { return COMMA; } <PARAMS>"," { return COMMA; }
<PARAMS>{whitespace}+ { /* ignore whitespaces */ } <PARAMS>{whitespace}+ { /* ignore whitespaces */ }
<PARAMS>$ { return TEXT; /* catch $ as text */ } <PARAMS>"$" { return TEXT; /* catch $ as text */ }
<PARAMS>. { fprintf(stderr, "error: illegal token '%s' in parameter block (line %d)\n", yytext, yylineno); exit(1); } <PARAMS>. { fprintf(stderr, "error: illegal token '%s' in parameter block (line %d)\n", yytext, yylineno); exit(1); }
<STATEMENT>[^%]+ { return TEXT; } <STATEMENT>[^%e]+ { return TEXT; }
<STATEMENT>% { return TEXT; /* catch % as text */ } <STATEMENT>{block_end} { return END; }
<STATEMENT>"%" { return TEXT; /* catch % as text */ }
<STATEMENT>"e" { return TEXT; /* catch e as text */ }
<STATEMENT>{statement_end} { if (isMetaSection) BEGIN(META_SECTION); else BEGIN(MAIN_SECTION); return STATEMENT_END; } <STATEMENT>{statement_end} { if (isMetaSection) BEGIN(META_SECTION); else BEGIN(MAIN_SECTION); return STATEMENT_END; }
<MAIN_SECTION>{params_begin} { fprintf(stderr, "warning: parameter block not allowed in main section (line %d); assuming to be text\n", yylineno); return TEXT; } <MAIN_SECTION>{params_begin} { fprintf(stderr, "warning: parameter block not allowed in main section (line %d); assuming to be text\n", yylineno); return TEXT; }