%option nounput %option bison-locations %{ #include #include #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 */ 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; import return IMPORT; module return MODULE; return return RETURN; struct return STRUCT; /* identifiers */ [a-zA-Z_][a-zA-Z_0-9]* { *yylval = new IdentifierNode(yytext); return IDENTIFIER; } /* strings */ \" build_string = ""; BEGIN(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]; %%