cxl/src/parser/parser.l

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);
}