/* * Copyright (c) Freescale Semiconductor, Inc. All rights reserved. * See included license file for license details. */ %option c++ /* %option prefix="Elftosb" */ %option yylineno %option never-interactive %option yyclass="ElftosbLexer" %option noyywrap %{ #include "ElftosbLexer.h" #include #include #include #include "HexValues.h" #include "Value.h" using namespace elftosb; //! Always executed before all other actions when a token is matched. //! This action just assign the first and last lines of the token to //! the current line. In most cases this is correct. #define YY_USER_ACTION do { \ m_location.m_firstLine = m_line; \ m_location.m_lastLine = m_line; \ } while (0); %} DIGIT [0-9] HEXDIGIT [0-9a-fA-F] BINDIGIT [0-1] IDENT [a-zA-Z_][a-zA-Z0-9_]* ESC \\(x{HEXDIGIT}{2}|.) /* start conditions */ %x blob mlcmt %% options { return TOK_OPTIONS; } constants { return TOK_CONSTANTS; } sources { return TOK_SOURCES; } filters { return TOK_FILTERS; } section { return TOK_SECTION; } extern { return TOK_EXTERN; } from { return TOK_FROM; } raw { return TOK_RAW; } load { return TOK_LOAD; } jump { return TOK_JUMP; } call { return TOK_CALL; } mode { return TOK_MODE; } if { return TOK_IF; } else { return TOK_ELSE; } defined { return TOK_DEFINED; } info { return TOK_INFO; } warning { return TOK_WARNING; } error { return TOK_ERROR; } sizeof { return TOK_SIZEOF; } dcd { return TOK_DCD; } hab { return TOK_HAB; } ivt { return TOK_IVT; } [whb]/[^a-zA-Z_0-9] { // must be followed by any non-ident char int_size_t theSize; switch (yytext[0]) { case 'w': theSize = kWordSize; break; case 'h': theSize = kHalfWordSize; break; case 'b': theSize = kByteSize; break; } m_symbolValue.m_int = new elftosb::SizedIntegerValue(0, theSize); return TOK_INT_SIZE; } true|yes { m_symbolValue.m_int = new elftosb::SizedIntegerValue(1, kWordSize); return TOK_INT_LITERAL; } false|no { m_symbolValue.m_int = new elftosb::SizedIntegerValue(0, kWordSize); return TOK_INT_LITERAL; } {IDENT} { m_symbolValue.m_str = new std::string(yytext); if (isSourceName(m_symbolValue.m_str)) { return TOK_SOURCE_NAME; } else { return TOK_IDENT; } } ({DIGIT}+|0x{HEXDIGIT}+|0b{BINDIGIT}+)([ \t]*[GMK])? { int base = 0; uint32_t value; int mult; // check for binary number if (yytext[0] == '0' && yytext[1] == 'b') { base = 2; // this is a binary number yytext += 2; // skip over the "0b" } // convert value value = (uint32_t)strtoul(yytext, NULL, base); // find multiplier switch (yytext[strlen(yytext) - 1]) { case 'G': mult = 1024 * 1024 * 1024; break; case 'M': mult = 1024 * 1024; break; case 'K': mult = 1024; break; default: mult = 1; break; } // set resulting symbol value m_symbolValue.m_int = new elftosb::SizedIntegerValue(value * mult, kWordSize); return TOK_INT_LITERAL; } \'(.|ESC)\'|\'(.|ESC){2}\'|\'(.|ESC){4}\' { uint32_t value = 0; int_size_t theSize; int len = strlen(yytext); if (len >= 3) { value = yytext[1]; theSize = kByteSize; } if (len >= 4) { value = (value << 8) | yytext[2]; theSize = kHalfWordSize; } if (len >= 6) { value = (value << 8) | yytext[3]; value = (value << 8) | yytext[4]; theSize = kWordSize; } m_symbolValue.m_int = new elftosb::SizedIntegerValue(value, theSize); return TOK_INT_LITERAL; } \$[\.\*a-zA-Z0-9_\[\]\^\?\-]+ { // remove $ from string m_symbolValue.m_str = new std::string(&yytext[1]); return TOK_SECTION_NAME; } "/*" { BEGIN(mlcmt); } "{{" { m_blob = new Blob(); m_blobFirstLine = yylineno; BEGIN(blob); } "{" { return '{'; } "}" { return '}'; } "(" { return '('; } ")" { return ')'; } "[" { return '['; } "]" { return ']'; } "=" { return '='; } "," { return ','; } ":" { return ':'; } ";" { return ';'; } "." { return '.'; } ">" { return '>'; } ".." { return TOK_DOT_DOT; } "+" { return '+'; } "-" { return '-'; } "*" { return '*'; } "/" { return '/'; } "%" { return '%'; } "~" { return '~'; } "^" { return '^'; } "<<" { return TOK_LSHIFT; } ">>" { return TOK_RSHIFT; } "&" { return '&'; } "|" { return '|'; } "**" { return TOK_POWER; } "<" { return '<'; } ">=" { return TOK_GEQ; } "<=" { return TOK_LEQ; } "==" { return TOK_EQ; } "!=" { return TOK_NEQ; } "&&" { return TOK_AND; } "||" { return TOK_OR; } "!" { return '!'; } \"(ESC|[^\"])*\" { // get rid of quotes yytext++; yytext[strlen(yytext) - 1] = 0; // processStringEscapes(yytext, yytext); m_symbolValue.m_str = new std::string(yytext); return TOK_STRING_LITERAL; } {HEXDIGIT}{2} { uint8_t x = (hexCharToInt(yytext[0]) << 4) | hexCharToInt(yytext[1]); m_blob->append(&x, 1); } "}}" { BEGIN(INITIAL); m_symbolValue.m_blob = m_blob; m_blob = NULL; m_location.m_firstLine = m_blobFirstLine; return TOK_BLOB; } \*\/ { // end of multi-line comment, return to initial state BEGIN(INITIAL); } (#|\/\/).*$ /* absorb single-line comment */ <*>[ \t] /* eat up whitespace in all states */ <*>(\r\n|\r|\n) { /* eat up whitespace and count lines in all states */ m_line++; } . /* ignore all other chars in a multi-line comment */ <*>. { /* all other chars produce errors */ char msg[50]; sprintf(msg, "unexpected character '%c' on line %d", yytext[0], m_line); LexerError(msg); } %% // verbatim code copied to the bottom of the output