1 /* 2 * Copyright (c) Freescale Semiconductor, Inc. All rights reserved. 3 * See included license file for license details. 4 */ 5 6 %option c++ 7 /* %option prefix="Elftosb" */ 8 %option yylineno 9 %option never-interactive 10 %option yyclass="ElftosbLexer" 11 %option noyywrap 12 13 %{ 14 #include "ElftosbLexer.h" 15 #include <stdlib.h> 16 #include <limits.h> 17 #include <string> 18 #include "HexValues.h" 19 #include "Value.h" 20 21 using namespace elftosb; 22 23 //! Always executed before all other actions when a token is matched. 24 //! This action just assign the first and last lines of the token to 25 //! the current line. In most cases this is correct. 26 #define YY_USER_ACTION do { \ 27 m_location.m_firstLine = m_line; \ 28 m_location.m_lastLine = m_line; \ 29 } while (0); 30 31 %} 32 33 DIGIT [0-9] 34 HEXDIGIT [0-9a-fA-F] 35 BINDIGIT [0-1] 36 IDENT [a-zA-Z_][a-zA-Z0-9_]* 37 ESC \\(x{HEXDIGIT}{2}|.) 38 39 /* start conditions */ 40 %x blob mlcmt 41 42 %% 43 44 options { return TOK_OPTIONS; } 45 constants { return TOK_CONSTANTS; } 46 sources { return TOK_SOURCES; } 47 filters { return TOK_FILTERS; } 48 section { return TOK_SECTION; } 49 extern { return TOK_EXTERN; } 50 from { return TOK_FROM; } 51 raw { return TOK_RAW; } 52 load { return TOK_LOAD; } 53 jump { return TOK_JUMP; } 54 call { return TOK_CALL; } 55 mode { return TOK_MODE; } 56 if { return TOK_IF; } 57 else { return TOK_ELSE; } 58 defined { return TOK_DEFINED; } 59 info { return TOK_INFO; } 60 warning { return TOK_WARNING; } 61 error { return TOK_ERROR; } 62 sizeof { return TOK_SIZEOF; } 63 dcd { return TOK_DCD; } 64 hab { return TOK_HAB; } 65 ivt { return TOK_IVT; } 66 67 [whb]/[^a-zA-Z_0-9] { // must be followed by any non-ident char 68 int_size_t theSize; 69 switch (yytext[0]) 70 { 71 case 'w': 72 theSize = kWordSize; 73 break; 74 case 'h': 75 theSize = kHalfWordSize; 76 break; 77 case 'b': 78 theSize = kByteSize; 79 break; 80 } 81 m_symbolValue.m_int = new elftosb::SizedIntegerValue(0, theSize); 82 return TOK_INT_SIZE; 83 } 84 85 true|yes { 86 m_symbolValue.m_int = new elftosb::SizedIntegerValue(1, kWordSize); 87 return TOK_INT_LITERAL; 88 } 89 90 false|no { 91 m_symbolValue.m_int = new elftosb::SizedIntegerValue(0, kWordSize); 92 return TOK_INT_LITERAL; 93 } 94 95 {IDENT} { 96 m_symbolValue.m_str = new std::string(yytext); 97 if (isSourceName(m_symbolValue.m_str)) 98 { 99 return TOK_SOURCE_NAME; 100 } 101 else 102 { 103 return TOK_IDENT; 104 } 105 } 106 107 ({DIGIT}+|0x{HEXDIGIT}+|0b{BINDIGIT}+)([ \t]*[GMK])? { 108 int base = 0; 109 uint32_t value; 110 int mult; 111 112 // check for binary number 113 if (yytext[0] == '0' && yytext[1] == 'b') 114 { 115 base = 2; // this is a binary number 116 yytext += 2; // skip over the "0b" 117 } 118 119 // convert value 120 value = (uint32_t)strtoul(yytext, NULL, base); 121 122 // find multiplier 123 switch (yytext[strlen(yytext) - 1]) 124 { 125 case 'G': 126 mult = 1024 * 1024 * 1024; 127 break; 128 case 'M': 129 mult = 1024 * 1024; 130 break; 131 case 'K': 132 mult = 1024; 133 break; 134 default: 135 mult = 1; 136 break; 137 } 138 139 // set resulting symbol value 140 m_symbolValue.m_int = new elftosb::SizedIntegerValue(value * mult, kWordSize); 141 return TOK_INT_LITERAL; 142 } 143 144 \'(.|ESC)\'|\'(.|ESC){2}\'|\'(.|ESC){4}\' { 145 uint32_t value = 0; 146 int_size_t theSize; 147 int len = strlen(yytext); 148 if (len >= 3) 149 { 150 value = yytext[1]; 151 theSize = kByteSize; 152 } 153 if (len >= 4) 154 { 155 value = (value << 8) | yytext[2]; 156 theSize = kHalfWordSize; 157 } 158 if (len >= 6) 159 { 160 value = (value << 8) | yytext[3]; 161 value = (value << 8) | yytext[4]; 162 theSize = kWordSize; 163 } 164 m_symbolValue.m_int = new elftosb::SizedIntegerValue(value, theSize); 165 return TOK_INT_LITERAL; 166 } 167 168 \$[\.\*a-zA-Z0-9_\[\]\^\?\-]+ { 169 // remove $ from string 170 m_symbolValue.m_str = new std::string(&yytext[1]); 171 return TOK_SECTION_NAME; 172 } 173 174 175 "/*" { BEGIN(mlcmt); } 176 177 "{{" { 178 m_blob = new Blob(); 179 m_blobFirstLine = yylineno; 180 BEGIN(blob); 181 } 182 183 "{" { return '{'; } 184 185 "}" { return '}'; } 186 187 "(" { return '('; } 188 189 ")" { return ')'; } 190 191 "[" { return '['; } 192 193 "]" { return ']'; } 194 195 "=" { return '='; } 196 197 "," { return ','; } 198 199 ":" { return ':'; } 200 201 ";" { return ';'; } 202 203 "." { return '.'; } 204 205 ">" { return '>'; } 206 207 ".." { return TOK_DOT_DOT; } 208 209 "+" { return '+'; } 210 211 "-" { return '-'; } 212 213 "*" { return '*'; } 214 215 "/" { return '/'; } 216 217 "%" { return '%'; } 218 219 "~" { return '~'; } 220 221 "^" { return '^'; } 222 223 "<<" { return TOK_LSHIFT; } 224 225 ">>" { return TOK_RSHIFT; } 226 227 "&" { return '&'; } 228 229 "|" { return '|'; } 230 231 "**" { return TOK_POWER; } 232 233 "<" { return '<'; } 234 235 ">=" { return TOK_GEQ; } 236 237 "<=" { return TOK_LEQ; } 238 239 "==" { return TOK_EQ; } 240 241 "!=" { return TOK_NEQ; } 242 243 "&&" { return TOK_AND; } 244 245 "||" { return TOK_OR; } 246 247 "!" { return '!'; } 248 249 \"(ESC|[^\"])*\" { 250 // get rid of quotes 251 yytext++; 252 yytext[strlen(yytext) - 1] = 0; 253 // processStringEscapes(yytext, yytext); 254 m_symbolValue.m_str = new std::string(yytext); 255 return TOK_STRING_LITERAL; 256 } 257 258 <blob>{HEXDIGIT}{2} { 259 uint8_t x = (hexCharToInt(yytext[0]) << 4) | hexCharToInt(yytext[1]); 260 m_blob->append(&x, 1); 261 } 262 263 <blob>"}}" { 264 BEGIN(INITIAL); 265 m_symbolValue.m_blob = m_blob; 266 m_blob = NULL; 267 m_location.m_firstLine = m_blobFirstLine; 268 return TOK_BLOB; 269 } 270 271 <mlcmt>\*\/ { 272 // end of multi-line comment, return to initial state 273 BEGIN(INITIAL); 274 } 275 276 277 (#|\/\/).*$ /* absorb single-line comment */ 278 279 <*>[ \t] /* eat up whitespace in all states */ 280 281 <*>(\r\n|\r|\n) { 282 /* eat up whitespace and count lines in all states */ 283 m_line++; 284 } 285 286 <mlcmt>. /* ignore all other chars in a multi-line comment */ 287 288 <*>. { 289 /* all other chars produce errors */ 290 char msg[50]; 291 sprintf(msg, "unexpected character '%c' on line %d", yytext[0], m_line); 292 LexerError(msg); 293 } 294 295 %% 296 297 // verbatim code copied to the bottom of the output 298 299 300