/* 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 . */ %{ #define YY_NO_UNISTD_H #define YY_USER_ACTION do { \ for (int i = 0; i < yyleng; i++) \ { \ if (yytext[i] == '\n') \ { \ this->location.lines(1); \ } \ else \ { \ this->location.columns(1); \ } \ } \ } while (0); #include #include "parser.hh" #undef YY_DECL #define YY_DECL yy::parser::symbol_type elna::boot::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] HEXADECIMAL 0[xX]{HIGIT}+ BIGIT [01] NATURAL [1-9][[:digit:]]* %% %{ this->location.step(); %} { \*\) BEGIN(INITIAL); [^*\n]+ ; /* Eat comment in chunks. */ \* ; /* Eat the lone star. */ \n+ { this->location.step(); } } \(\* BEGIN(IN_COMMENT); [ \t\r] { this->location.step(); } \n+ { } 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); } for { return yy::parser::make_FOR(this->location); } repeat { return yy::parser::make_REPEAT(this->location); } until { return yy::parser::make_UNTIL(this->location); } with { return yy::parser::make_WITH(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); } 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); } 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); } to { return yy::parser::make_TO(this->location); } {ID1}{ID2}* { return yy::parser::make_IDENTIFIER(yytext, this->location); } #{ID1}{ID2}* { return yy::parser::make_TRAIT(yytext + 1, this->location); } (0|{NATURAL})u|{HEXADECIMAL} { if (auto result = parse_integer(yytext, 0)) { return yy::parser::make_WORD(result.value(), this->location); } else { REJECT; } } (0|{NATURAL}|{HEXADECIMAL})u8 { if (auto result = parse_integer(yytext, 0)) { return yy::parser::make_WORD8(result.value(), this->location); } else { REJECT; } } (0|{NATURAL}|{HEXADECIMAL})u16 { if (auto result = parse_integer(yytext, 0)) { return yy::parser::make_WORD16(result.value(), this->location); } else { REJECT; } } (0|{NATURAL}|{HEXADECIMAL})u32 { if (auto result = parse_integer(yytext, 0)) { return yy::parser::make_WORD32(result.value(), this->location); } else { REJECT; } } (0|{NATURAL}|{HEXADECIMAL})u64 { if (auto result = parse_integer(yytext, 0)) { return yy::parser::make_WORD64(result.value(), this->location); } else { REJECT; } } 0|{NATURAL} { if (auto result = parse_integer(yytext, 10)) { return yy::parser::make_INTEGER(result.value(), this->location); } else { REJECT; } } (0|{NATURAL})i8 { if (auto result = parse_integer(yytext, 10)) { return yy::parser::make_INTEGER8(result.value(), this->location); } else { REJECT; } } (0|{NATURAL})i16 { if (auto result = parse_integer(yytext, 10)) { return yy::parser::make_INTEGER16(result.value(), this->location); } else { REJECT; } } (0|{NATURAL})i32 { if (auto result = parse_integer(yytext, 10)) { return yy::parser::make_INTEGER32(result.value(), this->location); } else { REJECT; } } (0|{NATURAL})i64 { if (auto result = parse_integer(yytext, 10)) { return yy::parser::make_INTEGER64(result.value(), this->location); } else { REJECT; } } 0[bB]{BIGIT}+ { if (auto result = parse_integer(yytext + 2, 2)) { return yy::parser::make_WORD(result.value(), this->location); } else { REJECT; } } 0[bB]{BIGIT}+u8 { if (auto result = parse_integer(yytext + 2, 2)) { return yy::parser::make_WORD8(result.value(), this->location); } else { REJECT; } } 0[bB]{BIGIT}+u16 { if (auto result = parse_integer(yytext + 2, 2)) { return yy::parser::make_WORD16(result.value(), this->location); } else { REJECT; } } 0[bB]{BIGIT}+u32 { if (auto result = parse_integer(yytext + 2, 2)) { return yy::parser::make_WORD32(result.value(), this->location); } else { REJECT; } } 0[bB]{BIGIT}+u64 { if (auto result = parse_integer(yytext + 2, 2)) { return yy::parser::make_WORD64(result.value(), this->location); } else { REJECT; } } [[:digit:]]+\.[[:digit:]]+([eE][+-]?[[:digit:]]+)? { errno = 0; double result = strtod(yytext, NULL); if (errno == ERANGE) { REJECT; } else { return yy::parser::make_FLOAT(result, this->location); } } [[:digit:]]+[eE][+-]?[[:digit:]]+ { errno = 0; double result = strtod(yytext, NULL); if (errno == ERANGE) { REJECT; } else { return yy::parser::make_FLOAT(result, this->location); } } '([^'\\\n]|\\.|\\\n)+' { std::optional result = parse_byte_literal(yytext); if (!result.has_value()) { REJECT; } return yy::parser::make_WORD8(std::make_pair(result.value(), integer_sign::_unsigned), this->location); } `([^`\\\n]|\\.|\\\n)+` { std::optional result = parse_character_literal(yytext); if (!result.has_value()) { REJECT; } return yy::parser::make_CHARACTER(result.value(), this->location); } \"([^\"\\\n]|\\.|\\\n)*\" { std::optional result = parse_string_literal(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_LEFT_BRACE(this->location); } \} { return yy::parser::make_RIGHT_BRACE(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_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(yytext[0]); driver.add_error(ss.str(), this->location); } %%