2020-12-20 00:00:00 +00:00
|
|
|
%option noinput nounput noyywrap
|
|
|
|
|
|
|
|
%{
|
|
|
|
#include <assert.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <inttypes.h>
|
2021-01-03 00:00:00 +00:00
|
|
|
#include <stdbool.h>
|
2020-12-20 00:00:00 +00:00
|
|
|
|
|
|
|
#include "./tree.h"
|
2021-01-03 00:00:00 +00:00
|
|
|
#include "./zone.h"
|
2020-12-20 00:00:00 +00:00
|
|
|
|
|
|
|
#include "generated/biner.y.h"
|
|
|
|
|
2020-12-22 00:00:00 +00:00
|
|
|
static inline biner_zone_ptr(char) strnew_(void);
|
2021-01-03 00:00:00 +00:00
|
|
|
static inline bool parse_int_(intmax_t* v, int base);
|
2020-12-22 00:00:00 +00:00
|
|
|
static inline void count_(void);
|
2020-12-20 00:00:00 +00:00
|
|
|
%}
|
|
|
|
|
|
|
|
D [0-9]
|
|
|
|
I [A-Za-z_]
|
|
|
|
H [0-9A-Fa-f]
|
|
|
|
|
|
|
|
%%
|
|
|
|
|
2021-01-03 00:00:00 +00:00
|
|
|
[ \t\r\n]+ count_();
|
|
|
|
"//".* count_();
|
2020-12-22 00:00:00 +00:00
|
|
|
[/][*][^*]*[*]+([^*/][^*]*[*]+)*[/] count_(); /* TODO: detect unterminated comment */
|
2020-12-20 00:00:00 +00:00
|
|
|
|
2020-12-26 00:00:00 +00:00
|
|
|
"==" { count_(); return EQUAL; }
|
|
|
|
"!=" { count_(); return NEQUAL; }
|
|
|
|
"<=" { count_(); return LESS_EQUAL; }
|
|
|
|
">=" { count_(); return GREATER_EQUAL; }
|
2020-12-31 00:00:00 +00:00
|
|
|
"&&" { count_(); return AND; }
|
|
|
|
"||" { count_(); return OR; }
|
|
|
|
"<<" { count_(); return BIT_LSHIFT; }
|
|
|
|
">>" { count_(); return BIT_RSHIFT; }
|
2020-12-26 00:00:00 +00:00
|
|
|
|
2020-12-26 00:00:00 +00:00
|
|
|
"const" { count_(); return CONST; }
|
2020-12-26 00:00:00 +00:00
|
|
|
"enum" { count_(); return ENUM; }
|
2020-12-22 00:00:00 +00:00
|
|
|
"struct" { count_(); return STRUCT; }
|
2020-12-26 00:00:00 +00:00
|
|
|
"union" { count_(); return UNION; }
|
2020-12-20 00:00:00 +00:00
|
|
|
|
2020-12-22 00:00:00 +00:00
|
|
|
{I}({I}|{D})* { yylval.ptr = strnew_(); count_(); return IDENT; }
|
2020-12-20 00:00:00 +00:00
|
|
|
|
2021-01-03 00:00:00 +00:00
|
|
|
{D}+ { return parse_int_(&yylval.i, 10)? INTEGER: OVERFLOWN_INTEGER; }
|
|
|
|
0[xX]{H}+ { return parse_int_(&yylval.i, 16)? INTEGER: OVERFLOWN_INTEGER; }
|
2020-12-20 00:00:00 +00:00
|
|
|
|
2021-01-03 00:00:00 +00:00
|
|
|
. { count_(); return yytext[0]; }
|
2020-12-20 00:00:00 +00:00
|
|
|
|
|
|
|
%%
|
2020-12-22 00:00:00 +00:00
|
|
|
static inline uintptr_t strnew_(void) {
|
|
|
|
return biner_zone_strnew(&biner_tree_parse_context_.zone, yytext);
|
|
|
|
}
|
2021-01-03 00:00:00 +00:00
|
|
|
static inline bool parse_int_(intmax_t* v, int base) {
|
|
|
|
assert(v != NULL);
|
|
|
|
|
|
|
|
char* end = NULL;
|
|
|
|
*v = strtoimax(yytext, &end, base);
|
|
|
|
return
|
|
|
|
((*v != INTMAX_MIN && *v != INTMAX_MAX) || errno != ERANGE) &&
|
|
|
|
(INT64_MIN <= *v && *v <= INT64_MAX) &&
|
|
|
|
(end != NULL && *end == 0);
|
2020-12-22 00:00:00 +00:00
|
|
|
}
|
|
|
|
static inline void count_(void) {
|
|
|
|
const char* s = yytext;
|
|
|
|
while (*s) {
|
|
|
|
if (*s == '\n') {
|
|
|
|
biner_tree_parse_context_.column = 0;
|
|
|
|
++biner_tree_parse_context_.line;
|
|
|
|
} else {
|
|
|
|
++biner_tree_parse_context_.column;
|
|
|
|
}
|
|
|
|
++s;
|
|
|
|
}
|
|
|
|
}
|