Files
vortex/src/scanner.lex
2013-10-08 02:20:32 -04:00

139 lines
4.5 KiB
Plaintext

/*******************************************************************************
HARPtools by Chad D. Kersey, Summer 2011
*******************************************************************************/
%option c++
%option noyywrap
%{
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <string>
#include <iostream>
#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
<INITIAL>\.def { BEGIN DEFARGS; return ASM_T_DIR_DEF; }
<INITIAL>\.perm { BEGIN PERMARGS; return ASM_T_DIR_PERM; }
<INITIAL>\.byte { BEGIN WORDARGS; return ASM_T_DIR_BYTE; }
<INITIAL>\.word { BEGIN WORDARGS; return ASM_T_DIR_WORD; }
<INITIAL>\.space { BEGIN WORDARGS; return ASM_T_DIR_SPACE; }
<INITIAL>\.string { BEGIN STRINGARGS; return ASM_T_DIR_STRING; }
<INITIAL>\.align { BEGIN ALIGNARGS; return ASM_T_DIR_ALIGN; }
<INITIAL>\.entry { BEGIN EMPTYARGS; return ASM_T_DIR_ENTRY; }
<INITIAL>\.global { BEGIN EMPTYARGS; return ASM_T_DIR_GLOBAL; }
<INITIAL>@p{num}{space}\? { yylval.u = read_number(YYText());
return ASM_T_PRED; }
<INITIAL>{sym}/: { BEGIN EATCOLON;
yylval.s = std::string(YYText());
return ASM_T_LABEL; }
<INITIAL>{sym} { BEGIN INSTARGS;
yylval.s = std::string(YYText());
return ASM_T_INST; }
<INITIAL>; {}
<INITIAL>{endl} {yyline++;}
<EATCOLON>: { BEGIN INITIAL; }
<INSTARGS>@p{num}{space}[,;]? { yylval.u = read_number(YYText());
return ASM_T_PREG; }
<INSTARGS>%r{num}{space}[,;]? { yylval.u = read_number(YYText());
return ASM_T_REG; }
<INSTARGS>#{num}{space}[,;]? { yylval.u = read_number(YYText());
return ASM_T_LIT; }
<INSTARGS>{sym} { yylval.s = std::string(YYText()); return ASM_T_SYM; }
<INSTARGS>{parenexp} { yylval.s = std::string(YYText()); return ASM_T_PEXP; }
<INSTARGS>{space} {}
<INSTARGS>; { BEGIN INITIAL; return ASM_T_DIR_END; }
<INSTARGS>{endl} { BEGIN INITIAL; yyline++; return ASM_T_DIR_END; }
<DEFARGS>{sym} { yylval.s = std::string(YYText());
return ASM_T_DIR_ARG_SYM; }
<DEFARGS>{num} { yylval.u = read_number(YYText());
return ASM_T_DIR_ARG_NUM; }
<DEFARGS>{endl} { yyline++; BEGIN INITIAL; }
<PERMARGS>r { return ASM_T_DIR_ARG_R; }
<PERMARGS>w { return ASM_T_DIR_ARG_W; }
<PERMARGS>x { return ASM_T_DIR_ARG_X; }
<PERMARGS>{endl} { BEGIN INITIAL; yyline++; return ASM_T_DIR_END; }
<WORDARGS>{num} { yylval.u = read_number(YYText());
return ASM_T_DIR_ARG_NUM; }
<WORDARGS>{endl} { BEGIN INITIAL; yyline++; return ASM_T_DIR_END; }
<STRINGARGS>{sym} { yylval.s = std::string(YYText());
return ASM_T_DIR_ARG_SYM; }
<STRINGARGS>\"([^\"]|\\\")*\" { BEGIN INITIAL;
yylval.s = std::string(YYText());
yylval.s = yylval.s.substr(1,
yylval.s.length() - 2);
return ASM_T_DIR_ARG_STRING; }
<ALIGNARGS>{num} { yylval.u = read_number(YYText());
return ASM_T_DIR_ARG_NUM; }
<ALIGNARGS>{endl} { yyline++; BEGIN INITIAL; }
<EMPTYARGS>{endl} { yyline++; BEGIN INITIAL; }
{space} { /*Ignore inter-token whitespace.*/ }
. { std::cout << "Unexpected character on line " << std::dec << yyline << '\n';
exit(1); }