📄 nasm-bison.y
字号:
/* * NASM-compatible bison parser * * Copyright (C) 2001 Peter Johnson, Michael Urman * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */%{#include <util.h>RCSID("$Id: nasm-bison.y 1168 2004-10-31 01:07:52Z peter $");#define YASM_LIB_INTERNAL#define YASM_EXPR_INTERNAL#include <libyasm.h>#ifdef STDC_HEADERS# include <math.h>#endif#include "modules/parsers/nasm/nasm-parser.h"#include "modules/parsers/nasm/nasm-defs.h"static void nasm_parser_directive (yasm_parser_nasm *parser_nasm, const char *name, yasm_valparamhead *valparams, /*@null@*/ yasm_valparamhead *objext_valparams);static int fix_directive_symrec(/*@null@*/ yasm_expr__item *ei, /*@null@*/ void *d);static void define_label(yasm_parser_nasm *parser_nasm, /*@only@*/ char *name, int local);#define nasm_parser_error(s) yasm__parser_error(cur_line, s)#define YYPARSE_PARAM parser_nasm_arg#define YYLEX_PARAM parser_nasm_arg#define parser_nasm ((yasm_parser_nasm *)parser_nasm_arg)#define nasm_parser_debug (parser_nasm->debug)/*@-usedef -nullassign -memtrans -usereleased -compdef -mustfree@*/%}%pure_parser%union { unsigned int int_info; char *str_val; yasm_intnum *intn; yasm_floatnum *flt; yasm_symrec *sym; unsigned long arch_data[4]; yasm_effaddr *ea; yasm_expr *exp; yasm_datavalhead datahead; yasm_dataval *data; yasm_bytecode *bc; yasm_valparamhead dir_valparams; yasm_valparam *dir_valparam; struct { yasm_insn_operands operands; int num_operands; } insn_operands; yasm_insn_operand *insn_operand; struct { char *name; int local; } label;}%token <intn> INTNUM%token <flt> FLTNUM%token <str_val> DIRECTIVE_NAME STRING FILENAME%token <int_info> SIZE_OVERRIDE%token <int_info> DECLARE_DATA%token <int_info> RESERVE_SPACE%token INCBIN EQU TIMES%token SEG WRT NOSPLIT%token <arch_data> INSN PREFIX REG SEGREG TARGETMOD%token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD START_SECTION_ID%token <str_val> ID LOCAL_ID SPECIAL_ID%token LINE%type <bc> line lineexp exp instr%type <ea> memaddr%type <exp> dvexpr expr direxpr%type <sym> explabel%type <label> label_id label%type <data> dataval%type <datahead> datavals%type <dir_valparams> directive_valparams%type <dir_valparam> directive_valparam%type <insn_operands> operands%type <insn_operand> operand%left ':'%left WRT%left '|'%left '^'%left '&'%left LEFT_OP RIGHT_OP%left '-' '+'%left '*' '/' SIGNDIV '%' SIGNMOD%nonassoc UNARYOP%nonassoc SEG%%input: /* empty */ | input line { parser_nasm->temp_bc = yasm_section_bcs_append(parser_nasm->cur_section, $2); if (parser_nasm->temp_bc) parser_nasm->prev_bc = parser_nasm->temp_bc; if (parser_nasm->save_input) yasm_linemap_add_source(parser_nasm->linemap, parser_nasm->temp_bc, parser_nasm->save_line[parser_nasm->save_last ^ 1]); yasm_linemap_goto_next(parser_nasm->linemap); };line: '\n' { $$ = (yasm_bytecode *)NULL; } | lineexp '\n' | LINE INTNUM '+' INTNUM FILENAME '\n' { /* %line indicates the line number of the *next* line, so subtract out * the increment when setting the line number. */ yasm_linemap_set(parser_nasm->linemap, $5, yasm_intnum_get_uint($2) - yasm_intnum_get_uint($4), yasm_intnum_get_uint($4)); yasm_intnum_destroy($2); yasm_intnum_destroy($4); yasm_xfree($5); $$ = (yasm_bytecode *)NULL; } | '[' { parser_nasm->state = DIRECTIVE; } directive ']' '\n' { $$ = (yasm_bytecode *)NULL; } | error '\n' { yasm__error(cur_line, N_("label or instruction expected at start of line")); $$ = (yasm_bytecode *)NULL; yyerrok; };lineexp: exp | TIMES expr exp { $$ = $3; yasm_bc_set_multiple($$, $2); } | label_id { yasm__warning(YASM_WARN_ORPHAN_LABEL, cur_line, N_("label alone on a line without a colon might be in error")); $$ = (yasm_bytecode *)NULL; define_label(parser_nasm, $1.name, $1.local); } | label_id ':' { $$ = (yasm_bytecode *)NULL; define_label(parser_nasm, $1.name, $1.local); } | label exp { $$ = $2; define_label(parser_nasm, $1.name, $1.local); } | label TIMES expr exp { $$ = $4; yasm_bc_set_multiple($$, $3); define_label(parser_nasm, $1.name, $1.local); } | label EQU expr { $$ = (yasm_bytecode *)NULL; yasm_symtab_define_equ(p_symtab, $1.name, $3, cur_line); yasm_xfree($1.name); };exp: instr | DECLARE_DATA datavals { $$ = yasm_bc_create_data(&$2, $1, cur_line); } | RESERVE_SPACE expr { $$ = yasm_bc_create_reserve($2, $1, cur_line); } | INCBIN STRING { $$ = yasm_bc_create_incbin($2, NULL, NULL, cur_line); } | INCBIN STRING ',' { $$ = yasm_bc_create_incbin($2, NULL, NULL, cur_line); } | INCBIN STRING ',' expr { $$ = yasm_bc_create_incbin($2, $4, NULL, cur_line); } | INCBIN STRING ',' expr ',' { $$ = yasm_bc_create_incbin($2, $4, NULL, cur_line); } | INCBIN STRING ',' expr ',' expr { $$ = yasm_bc_create_incbin($2, $4, $6, cur_line); };instr: INSN { $$ = yasm_arch_parse_insn(parser_nasm->arch, $1, 0, NULL, parser_nasm->prev_bc, cur_line); } | INSN operands { $$ = yasm_arch_parse_insn(parser_nasm->arch, $1, $2.num_operands, &$2.operands, parser_nasm->prev_bc, cur_line); yasm_ops_delete(&$2.operands, 0); } | INSN error { yasm__error(cur_line, N_("expression syntax error")); $$ = NULL; } | PREFIX instr { $$ = $2; yasm_arch_parse_prefix(parser_nasm->arch, $$, $1, cur_line); } | SEGREG instr { $$ = $2; yasm_arch_parse_seg_prefix(parser_nasm->arch, $$, $1[0], cur_line); };datavals: dataval { yasm_dvs_initialize(&$$); yasm_dvs_append(&$$, $1); } | datavals ',' dataval { yasm_dvs_append(&$1, $3); $$ = $1; } | datavals ',' { $$ = $1; };dataval: dvexpr { $$ = yasm_dv_create_expr($1); } | STRING { $$ = yasm_dv_create_string($1); } | error { yasm__error(cur_line, N_("expression syntax error")); $$ = (yasm_dataval *)NULL; };label: label_id | label_id ':' { $$ = $1; };label_id: ID { $$.name = $1; $$.local = 0; } | SPECIAL_ID { $$.name = $1; $$.local = 1; } | LOCAL_ID { $$.name = $1; $$.local = 1; };/* directives */directive: DIRECTIVE_NAME directive_val { yasm_xfree($1); } | DIRECTIVE_NAME error { yasm__error(cur_line, N_("invalid arguments to [%s]"), $1); yasm_xfree($1); }; /* $<str_val>0 is the DIRECTIVE_NAME */ /* After : is (optional) object-format specific extension */directive_val: directive_valparams { nasm_parser_directive(parser_nasm, $<str_val>0, &$1, NULL); } | directive_valparams ':' directive_valparams { nasm_parser_directive(parser_nasm, $<str_val>0, &$1, &$3); };directive_valparams: directive_valparam { yasm_vps_initialize(&$$); yasm_vps_append(&$$, $1); } | directive_valparams directive_valparam { yasm_vps_append(&$1, $2); $$ = $1; } | directive_valparams ',' directive_valparam { yasm_vps_append(&$1, $3); $$ = $1; };directive_valparam: direxpr { /* If direxpr is just an ID, put it in val and delete the expr. * Otherwise, we need to go through the expr and replace the current * (local) symrecs with the use of global ones. */ const /*@null@*/ yasm_symrec *vp_symrec; if ((vp_symrec = yasm_expr_get_symrec(&$1, 0))) { $$ = yasm_vp_create(yasm__xstrdup(yasm_symrec_get_name(vp_symrec)), NULL); yasm_expr_destroy($1); } else { yasm_expr__traverse_leaves_in($1, parser_nasm, fix_directive_symrec); $$ = yasm_vp_create(NULL, $1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -