%{ #include #include #include "dat.h" #include "fns.h" #define YYSTYPE Yystype static Sib mkSib(u32int index, u32int scale) { Sib s; s.index = index; s.scale = scale; return s; } int yyerror(char *s) { fprint(2, "oops: %s\n", s); return -1; } %} %start start %token CONST %token ERROR %token PREFIX %token OP %token REG8 %token REG32 %type basic_inst %type disp %type expr %type inst %type mem %type scale %type sib %% start : inst '\n' { return 1; } | error '\n' { return 0; } ; inst : basic_inst { $$ = $1; } | PREFIX inst { $$ = $2; $$.prefix |= $1; } ; basic_inst : OP { $$ = mkInst($1, 0); } | OP expr { $$ = mkInst($1, 1, $2); } | OP expr ',' expr { $$ = mkInst($1, 2, $2, $4); } | OP expr ',' expr ',' expr { $$ = mkInst($1, 3, $2, $4, $6); } ; expr : REG8 { $$ = mkExprReg8($1); } | REG32 { $$ = mkExprReg32($1); } | CONST { $$ = mkExprConst($1); } | mem { $$ = mkExprMem($1); } ; mem : disp '[' REG32 ']' sib { $$ = mkMem($1, $3, $5.index, $5.scale); } ; disp : /* nothing */ { $$ = 0; } | CONST { $$ = $1; } ; sib : /* nothing */ { $$ = mkSib(-1, -1); } | '[' REG32 scale ']' { $$ = mkSib($2, $3); } ; scale : /* nothing */ { $$ = 1; } | '*' CONST { $$ = $2; } ;