Last active
January 11, 2022 16:25
-
-
Save codebrainz/8587a1ddc8e020a71fef to your computer and use it in GitHub Desktop.
Simple assembly parser in Bison
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%{ | |
#include "stdinc.h" | |
#include "parser.h" | |
#include "tokens.h" | |
#include "lexer.h" | |
static void parser_error(YYLTYPE *locp, struct Parser* par, const char *message); | |
#define parser_lex(a,b,c) parser_lex(a,b,(c)->scanner) | |
%} | |
%locations | |
%pure-parser | |
%parse-param { struct Parser *parser } | |
%lex-param { struct Parser *parser } | |
%name-prefix "parser_" | |
%union { | |
char *str; | |
ptree_node_t *node; | |
} | |
%token <str> T_IDENT T_COMMENT | |
%token <str> T_HEXLIT T_BINLIT T_OCTLIT T_DECLIT T_FLTLIT T_CHRLIT T_STRLIT | |
%type <node> primary_expr unary_expr operand operand_list | |
label mnemonic instruction program_element | |
%destructor { ptree_node_free($$); } <node> | |
%destructor { free($$); } <str> | |
%start program | |
%% | |
primary_expr | |
: T_IDENT { $$ = ptree_ident_new($1, @1.first_line, @1.first_column); free($1); } | |
| T_HEXLIT { $$ = ptree_intlit_new($1, @1.first_line, @1.first_column); free($1); } | |
| T_BINLIT { $$ = ptree_intlit_new($1, @1.first_line, @1.first_column); free($1); } | |
| T_OCTLIT { $$ = ptree_intlit_new($1, @1.first_line, @1.first_column); free($1); } | |
| T_DECLIT { $$ = ptree_intlit_new($1, @1.first_line, @1.first_column); free($1); } | |
| T_FLTLIT { $$ = ptree_fltlit_new($1, @1.first_line, @1.first_column); free($1); } | |
| T_CHRLIT { $$ = ptree_chrlit_new($1, @1.first_line, @1.first_column); free($1); } | |
| T_STRLIT { $$ = ptree_strlit_new($1, @1.first_line, @1.first_column); free($1); } | |
| '(' operand ')' { $$ = $2; } | |
; | |
unary_expr | |
: primary_expr { $$ = $1; } | |
| '+' primary_expr { $$ = ptree_unop_new('+', $2, @1.first_line, @1.first_column); } | |
| '-' primary_expr { $$ = ptree_unop_new('-', $2, @1.first_line, @1.first_column); } | |
; | |
operand | |
: unary_expr { $$ = $1; } | |
| unary_expr '+' unary_expr { $$ = ptree_binop_new('+', $1, $3, @1.first_line, @1.first_column); } | |
| unary_expr '-' unary_expr { $$ = ptree_binop_new('-', $1, $3, @1.first_line, @1.first_column); } | |
; | |
operand_list | |
: operand { | |
$$ = ptree_root_new(); | |
ptree_node_add_child($$, $1); | |
} | |
| operand_list ',' operand { | |
ptree_node_add_child($$, $3); | |
} | |
; | |
label | |
: T_IDENT ':' { $$ = ptree_label_new($1, @1.first_line, @1.first_column); free($1); } | |
; | |
mnemonic: T_IDENT { $$ = ptree_mnemonic_new($1, @1.first_line, @1.first_column); free($1); } | |
instruction: mnemonic operand_list | |
{ | |
$$ = ptree_instruction_new(@1.first_line, @1.first_column); | |
ptree_node_add_child($$, $1); | |
ptree_node_t *it = $2->children; | |
while (it) { | |
ptree_node_t *next = it->next; | |
ptree_node_add_child($$, it); | |
it = next; | |
} | |
$2->children = NULL; | |
ptree_node_free($2); | |
} | |
; | |
program_element | |
: T_COMMENT { $$ = ptree_comment_new($1, @1.first_line, @1.first_column); free($1); } | |
| instruction { $$ = $1; } | |
| label { $$ = $1; } | |
; | |
program | |
: program_element { ptree_node_add_child(parser->root, $1); } | |
| program program_element { ptree_node_add_child(parser->root, $2); } | |
; | |
%% | |
static void parser_error(YYLTYPE *locp, struct Parser* par, const char *message) | |
{ | |
fprintf(stderr, "error:%d:%d: %s\n", | |
locp->first_line, locp->first_column, message); | |
exit(EXIT_FAILURE); | |
} | |
struct Parser* parser_init(struct Parser* par) | |
{ | |
memset(par, 0, sizeof(struct Parser)); | |
parser_lex_init(&par->scanner); | |
par->root = ptree_root_new(); | |
return par; | |
} | |
void parser_deinit(struct Parser* par) | |
{ | |
ptree_node_free(par->root); | |
parser_lex_destroy(par->scanner); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment