206 lines
6.1 KiB
Plaintext
206 lines
6.1 KiB
Plaintext
%option nounput
|
|
%option bison-locations
|
|
|
|
%{
|
|
|
|
#include "parser.h"
|
|
#include "parser.tab.h"
|
|
#include "String.h"
|
|
#include <stdlib.h>
|
|
|
|
#define YY_USER_ACTION yylloc->first_column += yyleng;
|
|
|
|
static String * build_string = NULL;
|
|
static size_t current_line = 1u;
|
|
static String * current_file = NULL;
|
|
void handle_loc(const char * input);
|
|
|
|
%}
|
|
|
|
%option noyywrap
|
|
|
|
%x str
|
|
|
|
%%
|
|
|
|
\+ return TOK_PLUS;
|
|
- return TOK_MINUS;
|
|
\* return TOK_TIMES;
|
|
\/ return TOK_DIVIDE;
|
|
% return TOK_MOD;
|
|
\^ return TOK_XOR;
|
|
= return TOK_ASSIGN;
|
|
== return TOK_EQUALS;
|
|
!= return TOK_NOTEQUALS;
|
|
\< return TOK_LESS;
|
|
\<= return TOK_LESSEQ;
|
|
\> return TOK_GREATER;
|
|
\>= return TOK_GREATEREQ;
|
|
&& return TOK_AND;
|
|
\|\| return TOK_OR;
|
|
! return TOK_NOT;
|
|
& return TOK_BITAND;
|
|
\| return TOK_BITOR;
|
|
~ return TOK_BITNOT;
|
|
\+\+ return TOK_INCREMENT;
|
|
-- return TOK_DECREMENT;
|
|
\<\< return TOK_LSHIFT;
|
|
\>\> return TOK_RSHIFT;
|
|
\+= return TOK_PLUSEQUALS;
|
|
-= return TOK_MINUSEQUALS;
|
|
\*= return TOK_TIMESEQUALS;
|
|
\/= return TOK_DIVIDEEQUALS;
|
|
%= return TOK_MODEQUALS;
|
|
\^= return TOK_XOREQUALS;
|
|
\<\<= return TOK_LSHIFTEQUALS;
|
|
\>\>= return TOK_RSHIFTEQUALS;
|
|
&= return TOK_BITANDEQUALS;
|
|
\|= return TOK_BITOREQUALS;
|
|
|
|
; return TOK_SEMICOLON;
|
|
: return TOK_COLON;
|
|
\? return TOK_QUESTION;
|
|
\. return TOK_DOT;
|
|
-\> return TOK_ARROW;
|
|
, return TOK_COMMA;
|
|
\.\.\. return TOK_ELLIPSES;
|
|
|
|
\{ return TOK_LCURLY;
|
|
\} return TOK_RCURLY;
|
|
\[ return TOK_LBRACKET;
|
|
\] return TOK_RBRACKET;
|
|
\( return TOK_LPAREN;
|
|
\) return TOK_RPAREN;
|
|
|
|
|
|
void return TOK_VOID;
|
|
char return TOK_CHAR;
|
|
short return TOK_SHORT;
|
|
int return TOK_INT;
|
|
long return TOK_LONG;
|
|
float return TOK_FLOAT;
|
|
double return TOK_DOUBLE;
|
|
|
|
signed return TOK_SIGNED;
|
|
unsigned return TOK_UNSIGNED;
|
|
|
|
volatile return TOK_VOLATILE;
|
|
static return TOK_STATIC;
|
|
const return TOK_CONST;
|
|
extern return TOK_EXTERN;
|
|
auto return TOK_AUTO;
|
|
register return TOK_REGISTER;
|
|
inline return TOK_INLINE;
|
|
|
|
struct return TOK_STRUCT;
|
|
union return TOK_UNION;
|
|
enum return TOK_ENUM;
|
|
|
|
typedef return TOK_TYPEDEF;
|
|
|
|
if return TOK_IF;
|
|
else return TOK_ELSE;
|
|
while return TOK_WHILE;
|
|
for return TOK_FOR;
|
|
do return TOK_DO;
|
|
goto return TOK_GOTO;
|
|
return return TOK_RETURN;
|
|
switch return TOK_SWITCH;
|
|
case return TOK_CASE;
|
|
default return TOK_DEFAULT;
|
|
break return TOK_BREAK;
|
|
continue return TOK_CONTINUE;
|
|
|
|
sizeof return TOK_SIZEOF;
|
|
|
|
|
|
L?'[^\\]' return TOK_CHAR_CONST;
|
|
L?'\\.' return TOK_CHAR_CONST;
|
|
L?'\\a' (void)'\a'; return TOK_CHAR_CONST;
|
|
L?'\\b' (void)'\b'; return TOK_CHAR_CONST;
|
|
L?'\\f' (void)'\f'; return TOK_CHAR_CONST;
|
|
L?'\\n' (void)'\n'; return TOK_CHAR_CONST;
|
|
L?'\\r' (void)'\r'; return TOK_CHAR_CONST;
|
|
L?'\\t' (void)'\t'; return TOK_CHAR_CONST;
|
|
L?'\\v' (void)'\v'; return TOK_CHAR_CONST;
|
|
L?'\\x[0-9A-Fa-f]{2}' return TOK_CHAR_CONST;
|
|
L?'\\[0-7]{1,3}' return TOK_CHAR_CONST;
|
|
[0-9]+([uU][lL]?[lL]?)? return TOK_INT_CONST;
|
|
0[xX][0-9a-fA-F]+([uU][lL]?[lL]?)? return TOK_INT_CONST;
|
|
([0-9]+\.[0-9]*|\.[0-9]+)([eE][-+]?[0-9]+)?[fFlL]? return TOK_FLOAT_CONST;
|
|
|
|
L?\" {
|
|
if (build_string != NULL)
|
|
{
|
|
String_free(build_string);
|
|
}
|
|
build_string = String_new("");
|
|
BEGIN(str);
|
|
}
|
|
<str>{
|
|
\" {
|
|
BEGIN(INITIAL);
|
|
return TOK_STR_CONST;
|
|
}
|
|
\\x[0-9A-Fa-f]{2} {
|
|
/* hexadecimal escape code */
|
|
unsigned int val;
|
|
(void)sscanf(yytext + 1, "%x", &val);
|
|
char v[2] = {(char)val, '\0'};
|
|
String_concat(build_string, v);
|
|
}
|
|
\\[0-7]{1,3} {
|
|
/* octal escape code */
|
|
unsigned int val;
|
|
(void)sscanf(yytext + 1, "%o", &val);
|
|
char v[2] = {(char)val, '\0'};
|
|
String_concat(build_string, v);
|
|
}
|
|
\\a String_concat(build_string, "\a");
|
|
\\b String_concat(build_string, "\b");
|
|
\\f String_concat(build_string, "\f");
|
|
\\n String_concat(build_string, "\n");
|
|
\\r String_concat(build_string, "\r");
|
|
\\t String_concat(build_string, "\t");
|
|
\\v String_concat(build_string, "\v");
|
|
\\. String_concat(build_string, &yytext[1]);
|
|
[^\\\"]+ String_concat(build_string, yytext);
|
|
}
|
|
|
|
[a-zA-Z_][a-zA-Z_0-9]* return TOK_IDENTIFIER;
|
|
|
|
^[ ]*#[ ]+[0-9]+[ ]+\".+\".*$ {
|
|
handle_loc(yytext);
|
|
}
|
|
\n {
|
|
yylloc->first_line++;
|
|
yylloc->first_column = 0;
|
|
yylloc->last_line++;
|
|
yylloc->last_column = 0;
|
|
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 = String_new_size(fname_start, fname_len);
|
|
}
|