diff options
Diffstat (limited to 'sfinae.y')
| -rw-r--r-- | sfinae.y | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/sfinae.y b/sfinae.y new file mode 100644 index 0000000..2e91b23 --- /dev/null +++ b/sfinae.y @@ -0,0 +1,64 @@ +%{ +#include "ast.h" +#include "lexer.h" + +#include <stdio.h> + +struct Node* program_root = NULL; + +void yyerror(const char* message); +%} + +%union +{ + char character; + struct Node* node; +} + +%token TOK_COLONCOLON +%token TOK_EMIT +%token TOK_COMMIT +%token TOK_DECLTYPE +%token TOK_DIFFERENCE +%token <character> TOK_CHAR + +%type <node> statements statement type value + +%% + +program + : statements + { program_root = $1; } + ; + +statements + : /* nothing */ + { $$ = NULL; } + | statements statement ';' + { $$ = node_append($1, $2); } + ; + +statement + : TOK_COLONCOLON TOK_EMIT '<' type '>' TOK_COLONCOLON TOK_COMMIT + { $$ = node_unary(STMT_EMIT, $4); } + ; + +type + : TOK_COLONCOLON TOK_DECLTYPE '(' value ')' + { $$ = node_unary(TYPE_DECLTYPE, $4); } + ; + +value + : TOK_COLONCOLON TOK_DIFFERENCE '<' TOK_CHAR ',' TOK_CHAR '>' + { $$ = node_binary(VALUE_DIFFERENCE, node_char($4), node_char($6)); } + ; + +%% + +void yyerror(const char* message) +{ + if (!lexer_failed()) + { + (void)fprintf(stderr, "line %d: %s, did you forget to commit\n", yylineno, message); + } +} |
