%{ #include #include #include #include #include /* Text value and integer value for parser */ static char *yylval; uint32_t yyival; /* Tokens */ #define SYSCALL 1 #define ADDRESS 2 #define NAME 3 /* Current file name */ static std::string filename; /* Error messages and exceptions */ static void err(char const *format, ...) { static char buf[256]; va_list args; va_start(args, format); vsnprintf(buf, 256, format, args); va_end(args); throw FxOS::SyntaxError(filename.c_str(), yylineno, buf); } %} %option prefix="symbols" %option noyywrap %option nounput syscall ^%[0-9A-Fa-f]{3,} address ^[0-9A-Fa-f]{8} name [a-zA-Z_][a-zA-Z_0-9.]* space [ \t]+ %% ^#[^\n]* ; {space} ; [\n] yylineno++; {syscall} { yyival = strtol(yytext+1, NULL, 16); return SYSCALL; } {address} { yyival = strtol(yytext, NULL, 16); return ADDRESS; } {name} { yylval = strdup(yytext); return NAME; } . { err("lex error near '%s'", yytext); } <> { return -1; } %% namespace FxOS { /* Load a symbol table into the disassembler */ void load_symbols(Buffer const &file, size_t start_offset, size_t start_line, SymbolTable &table) { YY_BUFFER_STATE buf = yy_scan_bytes(file.data.get() + start_offset, file.size - start_offset); yylineno = start_line; filename = file.path; /* Current symbol and line */ Symbol symbol; int line = -1; while(1) { int t = yylex(); if(line >= 0 && (yylineno != line || t != NAME || t == -1)) { /* Finalize current symbol */ if(symbol.name == "") err("%d: missing name", line); else table.add(symbol); symbol = Symbol(); } if(t == -1) break; if(t == SYSCALL) { symbol.type = Symbol::Syscall; symbol.value = yyival; line = yylineno; } else if(t == ADDRESS) { symbol.type = Symbol::Address; symbol.value = yyival; line = yylineno; } else if(t == NAME) { symbol.name = yylval; free(yylval); } } yy_delete_buffer(buf); } } /* namespace FxOS */