/******************************************************************************* HARPtools by Chad D. Kersey, Summer 2011 *******************************************************************************/ %option c++ %option noyywrap %{ #include #include #include #include #include #include #include #include "include/asm-tokens.h" #include "include/harpfloat.h" extern int lexerFloatBytes; static int64_t read_number(const char *s) { while (!isdigit(*s) && *s != '-' && *s != '+') s++; if (strchr(s, 'f') && !strchr(s, 'x') || strchr(s, '.')) { double d; sscanf(s, "%lf", &d); return Harp::Word_u(Harp::Float(d, lexerFloatBytes)); } else { long long u; sscanf(s, "%lli", &u); return u; } } static std::string label_name(const char *cs) { return std::string(cs, strlen(cs)-1); } struct rval_t { std::string s; uint64_t u; } yylval; unsigned yyline(1); using namespace HarpTools; %} %start DEFARGS PERMARGS WORDARGS STRINGARGS ALIGNARGS EMPTYARGS INSTARGS %start EATCOLON sym [A-Za-z_.][A-Za-z0-9_.]* decnum [1-9][0-9]* hexnum 0x[0-9a-f]+ octnum 0[0-7]* floatnum ([0-9]+f|[0-9]*\.[0-9]+) num [+-]?({decnum}|{hexnum}|{octnum}|{floatnum}) space [ \t]* peoperator ("+"|"-"|"*"|"/"|"%"|"&"|"|"|"^"|"<<"|">>"|"`") parenexp "("({num}|{sym}|{peoperator}|{space}|"("|")")+")" endl \r?\n %% \/\*([^*]|\*[^/]|{endl})*\*\/ { /* Ignore comments but keep line count consistent. */ for (const char *c = YYText(); *c; c++) if (*c == '\n') yyline++; } to \.def { BEGIN DEFARGS; return ASM_T_DIR_DEF; } \.perm { BEGIN PERMARGS; return ASM_T_DIR_PERM; } \.byte { BEGIN WORDARGS; return ASM_T_DIR_BYTE; } \.word { BEGIN WORDARGS; return ASM_T_DIR_WORD; } \.space { BEGIN WORDARGS; return ASM_T_DIR_SPACE; } \.string { BEGIN STRINGARGS; return ASM_T_DIR_STRING; } \.align { BEGIN ALIGNARGS; return ASM_T_DIR_ALIGN; } \.entry { BEGIN EMPTYARGS; return ASM_T_DIR_ENTRY; } \.global { BEGIN EMPTYARGS; return ASM_T_DIR_GLOBAL; } @p{num}{space}\? { yylval.u = read_number(YYText()); return ASM_T_PRED; } {sym}/: { BEGIN EATCOLON; yylval.s = std::string(YYText()); return ASM_T_LABEL; } {sym} { BEGIN INSTARGS; yylval.s = std::string(YYText()); return ASM_T_INST; } ; {} {endl} {yyline++;} : { BEGIN INITIAL; } @p{num}{space}[,;]? { yylval.u = read_number(YYText()); return ASM_T_PREG; } %r{num}{space}[,;]? { yylval.u = read_number(YYText()); return ASM_T_REG; } #{num}{space}[,;]? { yylval.u = read_number(YYText()); return ASM_T_LIT; } {sym} { yylval.s = std::string(YYText()); return ASM_T_SYM; } {parenexp} { yylval.s = std::string(YYText()); return ASM_T_PEXP; } {space} {} ; { BEGIN INITIAL; return ASM_T_DIR_END; } {endl} { BEGIN INITIAL; yyline++; return ASM_T_DIR_END; } {sym} { yylval.s = std::string(YYText()); return ASM_T_DIR_ARG_SYM; } {num} { yylval.u = read_number(YYText()); return ASM_T_DIR_ARG_NUM; } {endl} { yyline++; BEGIN INITIAL; } r { return ASM_T_DIR_ARG_R; } w { return ASM_T_DIR_ARG_W; } x { return ASM_T_DIR_ARG_X; } {endl} { BEGIN INITIAL; yyline++; return ASM_T_DIR_END; } {num} { yylval.u = read_number(YYText()); return ASM_T_DIR_ARG_NUM; } {endl} { BEGIN INITIAL; yyline++; return ASM_T_DIR_END; } {sym} { yylval.s = std::string(YYText()); return ASM_T_DIR_ARG_SYM; } \"([^\"]|\\\")*\" { BEGIN INITIAL; yylval.s = std::string(YYText()); yylval.s = yylval.s.substr(1, yylval.s.length() - 2); return ASM_T_DIR_ARG_STRING; } {num} { yylval.u = read_number(YYText()); return ASM_T_DIR_ARG_NUM; } {endl} { yyline++; BEGIN INITIAL; } {endl} { yyline++; BEGIN INITIAL; } {space} { /*Ignore inter-token whitespace.*/ } . { std::cout << "Unexpected character on line " << std::dec << yyline << '\n'; exit(1); }