%option nounput %option bison-locations %{ #include "parser.h" #include #include "Node.h" #include #define YY_USER_ACTION \ do { \ yylloc->first_column += yyleng; \ yylloc->last_column += yyleng; \ *yylval = new Node(NODE_TYPE_TOKEN); \ (*yylval)->token.fname = current_file; \ (*yylval)->token.line = current_line; \ (*yylval)->token.text = new std::string(yytext); \ } while(0); static std::string * build_string = nullptr; static size_t current_line = 1u; static std::string * current_file = nullptr; void handle_loc(const char * input); %} %option noyywrap %x str %% \+ return PLUS; - return MINUS; \* return TIMES; \/ return DIVIDE; % return MOD; \^ return XOR; = return ASSIGN; == return EQUALS; != return NOTEQUALS; \< return LESS; \<= return LESSEQ; \> return GREATER; \>= return GREATEREQ; && return AND; \|\| return OR; ! return NOT; & return BITAND; \| return BITOR; ~ return BITNOT; \+\+ return INCREMENT; -- return DECREMENT; \<\< return LSHIFT; \>\> return RSHIFT; \+= return ADD_ASSIGN; -= return SUB_ASSIGN; \*= return MUL_ASSIGN; \/= return DIV_ASSIGN; %= return MOD_ASSIGN; \^= return XOR_ASSIGN; \<\<= return LEFT_ASSIGN; \>\>= return RIGHT_ASSIGN; &= return AND_ASSIGN; \|= return OR_ASSIGN; ; return SEMICOLON; : return COLON; \? return QUESTION; \. return DOT; -\> return ARROW; , return COMMA; \.\.\. return ELLIPSIS; \{ return LCURLY; \} return RCURLY; \[ return LBRACKET; \] return RBRACKET; \( return LPAREN; \) return RPAREN; void return VOID; char return CHAR; short return SHORT; int return INT; long return LONG; float return FLOAT; double return DOUBLE; signed return SIGNED; unsigned return UNSIGNED; volatile return VOLATILE; static return STATIC; const return CONST; extern return EXTERN; auto return AUTO; register return REGISTER; inline return INLINE; struct return STRUCT; union return UNION; enum return ENUM; typedef return TYPEDEF; if return IF; else return ELSE; while return WHILE; for return FOR; do return DO; goto return GOTO; return return RETURN; switch return SWITCH; case return CASE; default return DEFAULT; break return BREAK; continue return CONTINUE; sizeof return SIZEOF; __attribute__ return ATTRIBUTE; __restrict return RESTRICT; L?'[^\\]' return CHAR_CONST; L?'\\.' return CHAR_CONST; L?'\\a' (void)'\a'; return CHAR_CONST; L?'\\b' (void)'\b'; return CHAR_CONST; L?'\\f' (void)'\f'; return CHAR_CONST; L?'\\n' (void)'\n'; return CHAR_CONST; L?'\\r' (void)'\r'; return CHAR_CONST; L?'\\t' (void)'\t'; return CHAR_CONST; L?'\\v' (void)'\v'; return CHAR_CONST; L?'\\x[0-9A-Fa-f]{2}' return CHAR_CONST; L?'\\[0-7]{1,3}' return CHAR_CONST; [0-9]+([uU][lL]?[lL]?)? return INT_CONST; 0[xX][0-9a-fA-F]+([uU][lL]?[lL]?)? return INT_CONST; ([0-9]+\.[0-9]*|\.[0-9]+)([eE][-+]?[0-9]+)?[fFlL]? return FLOAT_CONST; L?\" { if (build_string != nullptr) { delete build_string; } build_string = new std::string(); BEGIN(str); } { \" { BEGIN(INITIAL); (*yylval)->token.text = build_string; build_string = nullptr; return STRING_LITERAL; } \\x[0-9A-Fa-f]{2} { /* hexadecimal escape code */ unsigned int val; (void)sscanf(yytext + 1, "%x", &val); *build_string += (char)val; } \\[0-7]{1,3} { /* octal escape code */ unsigned int val; (void)sscanf(yytext + 1, "%o", &val); *build_string += (char)val; } \\a *build_string += '\a'; \\b *build_string += '\b'; \\f *build_string += '\f'; \\n *build_string += '\n'; \\r *build_string += '\r'; \\t *build_string += '\t'; \\v *build_string += '\v'; \\. *build_string += (char)yytext[1]; [^\\\"]+ *build_string += yytext; } [a-zA-Z_][a-zA-Z_0-9]* { if (is_type_name(yytext)) { return TYPE_NAME; } else { return IDENTIFIER; } } ^[ ]*#[ ]+[0-9]+[ ]+\".+\".*$ { handle_loc(yytext); } \n { yylloc->first_line++; yylloc->first_column = 1; yylloc->last_line++; yylloc->last_column = 1; current_line++; } [ \t\v] /* ignore whitespace */ %% void handle_loc(const char * input) { while ((*input < '0') || (*input > '9')) { input++; } current_line = (size_t)atol(input) - 1u; while (*input != '"') { input++; } input++; const char * fname_start = input; while (*input != '"') { input++; } size_t fname_len = (input - fname_start); current_file = new std::string(fname_start, fname_len); }