%{ #include "ast.h" #include "lexer.h" #include 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_VOID %token TOK_INT32 %token TOK_BYTE %token TOK_SIZE_T %token TOK_REMOVE_CV %token TOK_DECLTYPE %token TOK_DIFFERENCE %token TOK_SUM %token TOK_PRODUCT %token TOK_QUOTIENT %token TOK_CHAR %type 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_VOID { $$ = node_leaf(TYPE_VOID); } | TOK_COLONCOLON TOK_INT32 { $$ = node_leaf(TYPE_INT32); } | TOK_COLONCOLON TOK_BYTE { $$ = node_leaf(TYPE_BYTE); } | TOK_COLONCOLON TOK_SIZE_T { $$ = node_leaf(TYPE_SIZE); } | TOK_COLONCOLON TOK_REMOVE_CV '<' type '>' { $$ = node_unary(TYPE_REMOVE_CV, $4); } | 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)); } | TOK_COLONCOLON TOK_SUM '<' value ',' value '>' { $$ = node_binary(VALUE_SUM, $4, $6); } | TOK_COLONCOLON TOK_PRODUCT '<' value ',' value '>' { $$ = node_binary(VALUE_PRODUCT, $4, $6); } | TOK_COLONCOLON TOK_QUOTIENT '<' value ',' value '>' { $$ = node_binary(VALUE_QUOTIENT, $4, $6); } ; %% void yyerror(const char* message) { if (!lexer_failed()) { (void)fprintf(stderr, "line %d: %s, did you forget to commit\n", yylineno, message); } }