diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-02-15 04:10:38 +0100 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-02-15 04:10:38 +0100 |
| commit | 5959fbb5524bbeb05a96eb15aba59e961a3efcb7 (patch) | |
| tree | 811be9bb8fba9bec6ae549c50f9cf92000b259c9 /frontend/lexer.ll | |
| download | elna-5959fbb5524bbeb05a96eb15aba59e961a3efcb7.tar.gz | |
Initial commit
Diffstat (limited to 'frontend/lexer.ll')
| -rw-r--r-- | frontend/lexer.ll | 320 |
1 files changed, 320 insertions, 0 deletions
diff --git a/frontend/lexer.ll b/frontend/lexer.ll new file mode 100644 index 0000000..f14497b --- /dev/null +++ b/frontend/lexer.ll @@ -0,0 +1,320 @@ +/* Lexical analyzer. + Copyright (C) 2025 Free Software Foundation, Inc. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +%{ +#define YY_NO_UNISTD_H +#define YY_USER_ACTION this->location.columns(yyleng); + +#include <sstream> +#include "parser.hh" + +#undef YY_DECL +#define YY_DECL yy::parser::symbol_type elna::frontend::lexer::lex(driver& driver) +#define yyterminate() return yy::parser::make_YYEOF(this->location) +%} + +%option c++ noyywrap never-interactive +%option yyclass="lexer" + +%x IN_COMMENT + +ID1 [A-Za-z_] +ID2 [A-Za-z0-9_] +HIGIT [0-9a-fA-F] +BIGIT [01] + +%% +%{ + this->location.step(); +%} + +<IN_COMMENT>{ + \*\) BEGIN(INITIAL); + [^*\n]+ ; /* Eat comment in chunks. */ + \* ; /* Eat the lone star. */ + \n+ { + this->location.lines(yyleng); + this->location.step(); + } +} +\(\* BEGIN(IN_COMMENT); +[ \t\r] { + this->location.step(); +} +\n+ { + this->location.lines(yyleng); +} +if { + return yy::parser::make_IF(this->location); +} +then { + return yy::parser::make_THEN(this->location); +} +else { + return yy::parser::make_ELSE(this->location); +} +elsif { + return yy::parser::make_ELSIF(this->location); +} +while { + return yy::parser::make_WHILE(this->location); +} +do { + return yy::parser::make_DO(this->location); +} +proc { + return yy::parser::make_PROCEDURE(this->location); +} +begin { + return yy::parser::make_BEGIN_BLOCK(this->location); + } +end { + return yy::parser::make_END_BLOCK(this->location); +} +extern { + return yy::parser::make_EXTERN(this->location); +} +const { + return yy::parser::make_CONST(this->location); +} +var { + return yy::parser::make_VAR(this->location); +} +type { + return yy::parser::make_TYPE(this->location); +} +record { + return yy::parser::make_RECORD(this->location); +} +union { + return yy::parser::make_UNION(this->location); +} +true { + return yy::parser::make_BOOLEAN(true, this->location); +} +false { + return yy::parser::make_BOOLEAN(false, this->location); +} +nil { + return yy::parser::make_NIL(this->location); +} +\& { + return yy::parser::make_AND(this->location); +} +xor { + return yy::parser::make_XOR(this->location); +} +or { + return yy::parser::make_OR(this->location); +} +\| { + return yy::parser::make_PIPE(this->location); +} +\~ { + return yy::parser::make_NOT(this->location); +} +return { + return yy::parser::make_RETURN(this->location); +} +module { + return yy::parser::make_MODULE(this->location); +} +program { + return yy::parser::make_PROGRAM(this->location); +} +import { + return yy::parser::make_IMPORT(this->location); +} +cast { + return yy::parser::make_CAST(this->location); +} +defer { + return yy::parser::make_DEFER(this->location); +} +case { + return yy::parser::make_CASE(this->location); +} +of { + return yy::parser::make_OF(this->location); +} +{ID1}{ID2}* { + return yy::parser::make_IDENTIFIER(yytext, this->location); +} +#{ID1}{ID2}* { + return yy::parser::make_TRAIT(yytext + 1, this->location); +} +[[:digit:]]+u { + unsigned long result = strtoul(yytext, NULL, 10); + + if (errno == ERANGE) + { + REJECT; + } + else + { + return yy::parser::make_WORD(result, this->location); + } +} +[[:digit:]]+ { + long result = strtol(yytext, NULL, 10); + + if (errno == ERANGE) + { + REJECT; + } + else + { + return yy::parser::make_INTEGER(result, this->location); + } +} +0x{HIGIT}+ { + unsigned long result = strtoul(yytext, NULL, 16); + + if (errno == ERANGE) + { + REJECT; + } + else + { + return yy::parser::make_WORD(result, this->location); + } +} +0b{BIGIT}+ { + unsigned long result = strtoul(yytext, NULL, 2); + + if (errno == ERANGE) + { + REJECT; + } + else + { + return yy::parser::make_WORD(result, this->location); + } +} +[[:digit:]]+\.[[:digit:]]+ { + float result = strtof(yytext, NULL); + + if (errno == ERANGE) + { + REJECT; + } + else + { + return yy::parser::make_FLOAT(result, this->location); + } +} +'[[:print:]]+' { + std::optional<std::string> result = escape_string(yytext); + if (!result.has_value() || result.value().size() != 1) + { + REJECT; + } + return yy::parser::make_CHARACTER(result.value(), this->location); +} +\"[[:print:]]*\" { + std::optional<std::string> result = escape_string(yytext); + if (!result.has_value()) + { + REJECT; + } + return yy::parser::make_STRING(result.value(), this->location); +} +\( { + return yy::parser::make_LEFT_PAREN(this->location); +} +\) { + return yy::parser::make_RIGHT_PAREN(this->location); +} +\[ { + return yy::parser::make_LEFT_SQUARE(this->location); +} +\] { + return yy::parser::make_RIGHT_SQUARE(this->location); +} +\<\< { + return yy::parser::make_SHIFT_LEFT(this->location); +} +\>\> { + return yy::parser::make_SHIFT_RIGHT(this->location); +} +\>= { + return yy::parser::make_GREATER_EQUAL(this->location); +} +\<= { + return yy::parser::make_LESS_EQUAL(this->location); +} +\> { + return yy::parser::make_GREATER_THAN(this->location); +} +\< { + return yy::parser::make_LESS_THAN(this->location); +} +\<\> { + return yy::parser::make_NOT_EQUAL(this->location); +} += { + return yy::parser::make_EQUALS(this->location); +} +; { + return yy::parser::make_SEMICOLON(this->location); +} +\. { + return yy::parser::make_DOT(this->location); +} +, { + return yy::parser::make_COMMA(this->location); +} +\+ { + return yy::parser::make_PLUS(this->location); +} +\-> { + return yy::parser::make_ARROW(this->location); +} +\- { + return yy::parser::make_MINUS(this->location); +} +\* { + return yy::parser::make_MULTIPLICATION(this->location); +} +\/ { + return yy::parser::make_DIVISION(this->location); +} +% { + return yy::parser::make_REMAINDER(this->location); +} +:= { + return yy::parser::make_ASSIGNMENT(this->location); +} +: { + return yy::parser::make_COLON(this->location); +} +\^ { + return yy::parser::make_HAT(this->location); +} +@ { + return yy::parser::make_AT(this->location); +} +! { + return yy::parser::make_EXCLAMATION(this->location); +} +. { + std::stringstream ss; + + ss << "Illegal character 0x" << std::hex << static_cast<unsigned int>(yytext[0]); + driver.add_error<syntax_error>(ss.str(), driver.input_file, this->location); +} +%% |
