225 lines
6.0 KiB
Plaintext
225 lines
6.0 KiB
Plaintext
%option nounput
|
|
%option bison-locations
|
|
|
|
%{
|
|
|
|
#include "parser.h"
|
|
#include <stdlib.h>
|
|
#include "Node.h"
|
|
#include <string>
|
|
|
|
#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);
|
|
}
|
|
<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);
|
|
}
|