%{ #include #include #include #include "parser.h" #define SETVALUE(v) yylval.arg = (struct argument) { .value = (v) } #define SETSTR(s) yylval.str = strdup(s) static int intlit(const char *s, int base, long *out) { errno = 0; *out = strtol(s, NULL, base); return errno == ERANGE ? T_BADINT : T_INT; } %} %option outfile="lexer.c" header-file="lexer.h" %option noyywrap never-interactive %s inst %s args LABEL [_a-zA-Z][_a-zA-Z0-9]* COMMENT #[^\n]* SP [ \t] EOI [ \t\n#] REGNUM [0-7] DEC [0-9] HEX [0-9a-f] %% {SP}+ { BEGIN(inst); return T_SPACE; } {LABEL} { SETSTR(yytext); return T_LABEL; } :{SP}* { BEGIN(inst); return T_COLON; } add/{EOI} { BEGIN(args); return T_ADD; } sub/{EOI} { BEGIN(args); return T_SUB; } mul/{EOI} { BEGIN(args); return T_MUL; } div/{EOI} { BEGIN(args); return T_DIV; } and/{EOI} { BEGIN(args); return T_AND; } or/{EOI} { BEGIN(args); return T_OR; } xor/{EOI} { BEGIN(args); return T_XOR; } lsl/{EOI} { BEGIN(args); return T_LSL; } lsr/{EOI} { BEGIN(args); return T_LSR; } asl/{EOI} { BEGIN(args); return T_ASL; } asr/{EOI} { BEGIN(args); return T_ASR; } rol/{EOI} { BEGIN(args); return T_ROL; } ror/{EOI} { BEGIN(args); return T_ROR; } not/{EOI} { BEGIN(args); return T_NOT; } neg/{EOI} { BEGIN(args); return T_NEG; } btc/{EOI} { BEGIN(args); return T_BTC; } bts/{EOI} { BEGIN(args); return T_BTS; } mov/{EOI} { BEGIN(args); return T_MOV; } st\.b/{EOI} { BEGIN(args); return T_ST_B; } st\.w/{EOI} { BEGIN(args); return T_ST_W; } ld\.bl/{EOI} { BEGIN(args); return T_LD_BL; } ld\.bh/{EOI} { BEGIN(args); return T_LD_BH; } ld\.w/{EOI} { BEGIN(args); return T_LD_W; } ldi\.bl/{EOI} { BEGIN(args); return T_LDI_BL; } ldi\.bh/{EOI} { BEGIN(args); return T_LDI_BH; } beq/{EOI} { BEGIN(args); return T_BEQ; } bne/{EOI} { BEGIN(args); return T_BNE; } bgt/{EOI} { BEGIN(args); return T_BGT; } bge/{EOI} { BEGIN(args); return T_BGE; } blt/{EOI} { BEGIN(args); return T_BLT; } ble/{EOI} { BEGIN(args); return T_BLE; } bra/{EOI} { BEGIN(args); return T_BRA; } jmp/{EOI} { BEGIN(args); return T_JMP; } addpc/{EOI} { BEGIN(args); return T_ADDPC; } nop/{EOI} { BEGIN(args); return T_NOP; } r{REGNUM} { SETVALUE(yytext[1]-'0'); return T_REG; } @r{REGNUM} { SETVALUE(yytext[2]-'0'); return T_REGPTR; } [-+]?{DEC}+ { return intlit(yytext, 10, &yylval.lval); } 0x{HEX}+ { return intlit(yytext+2, 16, &yylval.lval); } {SP}*,{SP}* { return T_COMMA; } {LABEL} { SETSTR(yytext); return T_LABEL; } {SP}*{COMMENT}?\n { BEGIN(INITIAL); return T_EOL; } {SP}*{COMMENT} { BEGIN(INITIAL); return T_EOL; } {SP}+ { return T_SPACE; } <> { return 0; } <> { BEGIN(INITIAL); return T_EOL; } %%