/* Source code for RCC-Legacy. Copyright (C) 2026 Richard Qin This file is part of RCC. RCC 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. RCC 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 RCC; see the file LICENSE. If not see . */ %{ /* lexer.l - SysY2022 Lexer */ #include "rcc/ast.h" #include "parser.tab.h" #include #include // Line number tracking int yylineno_val = 1; #define YY_USER_ACTION yylloc.first_line = yylineno_val; using namespace rcc; %} %option noyywrap nounput noinput /* Exclusive start condition: multi-line comments */ %x COMMENT %% /* ─── Whitespace and Newlines ─── */ [ \t\r]+ { /* skip whitespace */ } \n { yylineno_val++; } /* ─── Comments ─── */ "//"[^\n]* { /* single-line comment */ } "/*" { BEGIN(COMMENT); } "*/" { BEGIN(INITIAL); } \n { yylineno_val++; } . { /* eat anything inside comment */ } /* ─── Keywords ─── */ "int" { return T_INT; } "float" { return T_FLOAT; } "void" { return T_VOID; } "const" { return T_CONST; } "if" { return T_IF; } "else" { return T_ELSE; } "while" { return T_WHILE; } "break" { return T_BREAK; } "continue" { return T_CONTINUE; } "return" { return T_RETURN; } /* ─── Integer Constants (Hex > Octal > Decimal, order is important) ─── */ 0[xX][0-9a-fA-F]+ { yylval.int_val = static_cast(strtoul(yytext, nullptr, 16)); return INT_CONST; } 0[0-7]+ { yylval.int_val = static_cast(strtoul(yytext, nullptr, 8)); return INT_CONST; } [0-9]+ { yylval.int_val = static_cast(strtoul(yytext, nullptr, 10)); return INT_CONST; } /* ─── Floating Point Constants (Hex float + Decimal float) ─── */ 0[xX][0-9a-fA-F]*\.[0-9a-fA-F]+([pP][+-]?[0-9]+)? { yylval.float_val = strtof(yytext, nullptr); return FLOAT_CONST; } 0[xX][0-9a-fA-F]+\.[0-9a-fA-F]*([pP][+-]?[0-9]+)? { yylval.float_val = strtof(yytext, nullptr); return FLOAT_CONST; } 0[xX][0-9a-fA-F]+[pP][+-]?[0-9]+ { yylval.float_val = strtof(yytext, nullptr); return FLOAT_CONST; } [0-9]*\.[0-9]+([eE][+-]?[0-9]+)? { yylval.float_val = strtof(yytext, nullptr); return FLOAT_CONST; } [0-9]+\.[0-9]*([eE][+-]?[0-9]+)? { yylval.float_val = strtof(yytext, nullptr); return FLOAT_CONST; } [0-9]+[eE][+-]?[0-9]+ { yylval.float_val = strtof(yytext, nullptr); return FLOAT_CONST; } /* ─── Identifiers ─── */ [a-zA-Z_][a-zA-Z0-9_]* { yylval.str_val = strdup(yytext); return IDENT; } /* ─── Multi-character Operators ─── */ "&&" { return T_AND; } "||" { return T_OR; } "<=" { return T_LE; } ">=" { return T_GE; } "==" { return T_EQ; } "!=" { return T_NE; } /* ─── Format Strings (for putf only) ─── */ \"[^\"]*\" { yylval.str_val = strdup(yytext); return STRING_CONST; } /* ─── Single-character Operators and Delimiters, return ASCII directly ─── */ . { return yytext[0]; } %%