| /* |
| * blobtool - Compiler/Decompiler for data blobs with specs |
| * Copyright (C) 2017 Damien Zammit <damien@zamaudio.com> |
| * |
| * This program is free software: you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation, either version 3 of the License, or |
| * (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| */ |
| |
| %{ |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include "blobtool.tab.h" |
| |
| extern struct blob binary; |
| |
| unsigned int parsehex (char *s) |
| { |
| unsigned int i, nib, val = 0; |
| unsigned int nibs = strlen(s) - 2; |
| |
| for (i = 2; i < nibs + 2; i++) { |
| if (s[i] >= '0' && s[i] <= '9') { |
| nib = s[i] - '0'; |
| } else if (s[i] >= 'a' && s[i] <= 'f') { |
| nib = s[i] - 'a' + 10; |
| } else if (s[i] >= 'A' && s[i] <= 'F') { |
| nib = s[i] - 'A' + 10; |
| } else { |
| return 0; |
| } |
| val |= nib << (((nibs - 1) - (i - 2)) * 4); |
| } |
| return val; |
| } |
| |
| char* stripquotes (char *string) |
| { |
| char *stripped; |
| unsigned int len = strlen(string); |
| if (len >= 2 && string[0] == '\"' && string[len-1] == '\"') { |
| stripped = (char *) malloc (len - 2 + 1); |
| snprintf (stripped, len - 2 + 1, "%s", string+1); |
| stripped[len-2] = '\0'; |
| return stripped; |
| } else { |
| return 0; |
| } |
| } |
| |
| %} |
| |
| %option noyywrap |
| %option nounput |
| |
| DIGIT1to9 [1-9] |
| DIGIT [0-9] |
| DIGITS {DIGIT}+ |
| INT {DIGIT}|{DIGIT1to9}{DIGITS}|-{DIGIT}|-{DIGIT1to9}{DIGITS} |
| FRAC [.]{DIGITS} |
| E [eE][+-]? |
| EXP {E}{DIGITS} |
| HEX_DIGIT [0-9a-fA-F] |
| HEX_DIGITS {HEX_DIGIT}+ |
| NUMBER {INT}|{INT}{FRAC}|{INT}{EXP}|{INT}{FRAC}{EXP} |
| UNICODECHAR \\u{HEX_DIGIT}{HEX_DIGIT}{HEX_DIGIT}{HEX_DIGIT} |
| ALPHA [a-zA-Z] |
| SPECIAL [()\[\]"'@_\-+:;/\\.,<> ] |
| VARCHAR {ALPHA}|{DIGIT}|{SPECIAL} |
| CHAR {VARCHAR}|{UNICODECHAR} |
| CHARS {CHAR}+ |
| QUOTE ["] |
| HEX_PREFIX [0][x] |
| HEX {HEX_PREFIX}{HEX_DIGITS} |
| STRING {QUOTE}{QUOTE}|{QUOTE}{CHARS}{QUOTE} |
| COMMENT [#]{CHARS}[\n]|[#]\n |
| |
| %% |
| |
| {STRING} { |
| yylval.str = stripquotes(yytext); |
| return name; |
| }; |
| |
| {NUMBER} { |
| yylval.u32 = atoi(yytext); |
| return val; |
| }; |
| |
| {HEX} { |
| yylval.u32 = parsehex(yytext); |
| return val; |
| }; |
| |
| \{ { |
| return '{'; |
| }; |
| |
| \} { |
| return '}'; |
| }; |
| |
| \[ { |
| return '['; |
| }; |
| |
| \] { |
| return ']'; |
| }; |
| |
| , { |
| return ','; |
| }; |
| |
| : { |
| return ':'; |
| }; |
| |
| = { |
| return '='; |
| }; |
| |
| [ \t\n]+ /* ignore whitespace */; |
| |
| {COMMENT} /* ignore comments */ |
| |
| \% { |
| return '%'; |
| }; |
| |
| <<EOF>> { return eof; }; |
| |
| %% |
| |
| void set_input_string(char* in) { |
| yy_scan_string(in); |
| } |
| |