152 lines
3.2 KiB
Plaintext
152 lines
3.2 KiB
Plaintext
|
|
%option nounput
|
|
%option bison-locations
|
|
|
|
%{
|
|
|
|
#include <stdint.h>
|
|
#include <string>
|
|
#include "parser.h"
|
|
using namespace std;
|
|
static string build_string;
|
|
|
|
static uint64_t parseInt(const char * text, int base)
|
|
{
|
|
uint64_t val = 0;
|
|
for (const char * p = text; *p != '\0'; p++)
|
|
{
|
|
int digit = -1;
|
|
if (*p >= '0' && *p <= '9') digit = *p - '0';
|
|
else if (*p >= 'A' && *p <= 'Z') digit = *p - 'A';
|
|
else if (*p >= 'a' && *p <= 'z') digit = *p - 'a';
|
|
if (digit != -1)
|
|
{
|
|
val *= base;
|
|
val += digit;
|
|
}
|
|
}
|
|
return val;
|
|
}
|
|
|
|
%}
|
|
|
|
%x str
|
|
|
|
%%
|
|
|
|
/* operators */
|
|
:= return ASSIGN;
|
|
::= return DASSIGN;
|
|
== return DEQUALS;
|
|
\/ return DIVIDE;
|
|
= return EQUALS;
|
|
\> return GREATER;
|
|
\< return LESS;
|
|
=~ return MATCH;
|
|
- return MINUS;
|
|
% return MOD;
|
|
\+ return PLUS;
|
|
\* return STAR;
|
|
|
|
/* punctuation */
|
|
: return COLON;
|
|
, return COMMA;
|
|
:: return DCOLON;
|
|
\$ return DOLLAR;
|
|
\. return DOT;
|
|
\<- return FROM;
|
|
\? return QUESTION;
|
|
; return SEMICOLON;
|
|
|
|
\{ return LCURLY;
|
|
\} return RCURLY;
|
|
\[ return LBRACKET;
|
|
\] return RBRACKET;
|
|
\( return LPAREN;
|
|
\) return RPAREN;
|
|
|
|
/* numeric literals */
|
|
[0-9][0-9_]* {
|
|
*yylval = new IntegerNode(parseInt(yytext, 10));
|
|
return INT_LITERAL;
|
|
}
|
|
0x[0-9A-Fa-f][0-9A-Fa-f_]* {
|
|
*yylval = new IntegerNode(parseInt(yytext + 2, 16));
|
|
return INT_LITERAL;
|
|
}
|
|
0b[01][01_]* {
|
|
*yylval = new IntegerNode(parseInt(yytext + 2, 2));
|
|
return INT_LITERAL;
|
|
}
|
|
[0-9]*\.[0-9]+([eE]-?[0-9]+)? {
|
|
double val;
|
|
(void) sscanf(yytext, "%lf", &val);
|
|
*yylval = new DoubleNode(val);
|
|
return REAL_LITERAL;
|
|
}
|
|
|
|
/* primitive types */
|
|
bool return BOOL;
|
|
byte return BYTE;
|
|
ubyte return UBYTE;
|
|
char return CHAR;
|
|
wchar return WCHAR;
|
|
short return SHORT;
|
|
ushort return USHORT;
|
|
int return INT;
|
|
uint return UINT;
|
|
long return LONG;
|
|
ulong return ULONG;
|
|
float return FLOAT;
|
|
double return DOUBLE;
|
|
|
|
/* keywords */
|
|
c return C;
|
|
false return FALSE;
|
|
import return IMPORT;
|
|
module return MODULE;
|
|
return return RETURN;
|
|
struct return STRUCT;
|
|
true return TRUE;
|
|
|
|
/* identifiers */
|
|
[a-zA-Z_][a-zA-Z_0-9]* {
|
|
*yylval = new IdentifierNode(yytext);
|
|
return IDENTIFIER;
|
|
}
|
|
|
|
/* strings */
|
|
\" build_string = ""; BEGIN(str);
|
|
<str>{
|
|
|
|
\" {
|
|
/* end of the string literal */
|
|
BEGIN(INITIAL);
|
|
*yylval = new StringNode(build_string);
|
|
return STRING_LITERAL;
|
|
}
|
|
\\x[0-9A-Fa-f]{2} {
|
|
/* hexadecimal escape code */
|
|
unsigned int val;
|
|
(void) sscanf(yytext + 2, "%x", &val);
|
|
build_string += (char) val;
|
|
}
|
|
\\n build_string += '\n';
|
|
\\t build_string += '\t';
|
|
\\r build_string += '\r';
|
|
\\b build_string += '\b';
|
|
\\f build_string += '\f';
|
|
\\(.|\n) build_string += yytext[1];
|
|
[^\\\"]+ build_string += yytext;
|
|
|
|
}
|
|
|
|
/* whitespace */
|
|
\n yylloc->first_line++; yylloc->last_line++;
|
|
[ \t\v] /* ignore whitespace */
|
|
|
|
/* anything else */
|
|
. return yytext[0];
|
|
|
|
%%
|