From 4def48d206acdabff0717961a47e5bd658721a3c Mon Sep 17 00:00:00 2001 From: bronku Date: Tue, 25 Nov 2025 15:36:51 +0100 Subject: [PATCH] indent fix --- src/indent_helper.hpp | 40 ++++++++++++++-------------------------- src/lexer.l | 26 ++++---------------------- src/scanner.hpp | 21 +++++++++++++++++++-- 3 files changed, 37 insertions(+), 50 deletions(-) diff --git a/src/indent_helper.hpp b/src/indent_helper.hpp index 978e7ef..9e27916 100644 --- a/src/indent_helper.hpp +++ b/src/indent_helper.hpp @@ -13,17 +13,17 @@ public: { int current = indent_stack.top(); + if (spaces == current) + { + return 0; + } + if (spaces > current) { indent_stack.push(spaces); return 1; } - if (spaces == current) - { - return 0; - } - pending_dedents = 0; while (indent_stack.top() > spaces) { @@ -31,35 +31,23 @@ public: pending_dedents++; } - if (indent_stack.top() != spaces) - { - throw std::runtime_error("Indentation error"); - } - - return -1; - } - - bool hasPendingDedents() const - { - return pending_dedents > 0; - } - - void consumePendingDedent() - { if (pending_dedents > 0) { pending_dedents--; + return -1; } + + return 0; } - int flushAllDedents() + // returns false on failure + bool consumeDedent() { - int total_dedents = 0; - while (indent_stack.size() > 1) + if (pending_dedents <= 0) { - indent_stack.pop(); - total_dedents++; + return false; } - return total_dedents; + pending_dedents--; + return true; } }; \ No newline at end of file diff --git a/src/lexer.l b/src/lexer.l index bcf91f5..9658e35 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -7,18 +7,13 @@ #include "scanner.hpp" #include "indent_helper.hpp" -IndentHelper indent_helper; -bool at_line_start = true; %} %% +^[ \t]*\r?\n { /* Ignore lines containing whitespace only */ } +^[ \t]*#.*\n { /* Ignore comment-only lines */ } ^[ \t]* { - if (!at_line_start) { - REJECT; - } - at_line_start = false; - int spaces = 0; for (int i = 0; i < yyleng; i++) spaces += (yytext[i] == '\t') ? 8 : 1; @@ -28,10 +23,7 @@ bool at_line_start = true; if (result < 0) return yy::parser::token::TOK_DEDENT; } -\n { - at_line_start = true; - return yy::parser::token::TOK_NEWLINE; -} +\n { return yy::parser::token::TOK_NEWLINE; } def { return yy::parser::token::TOK_KW_DEF; } if { return yy::parser::token::TOK_KW_IF; } @@ -54,15 +46,5 @@ in { return yy::parser::token::TOK_KW_IN; } [0-9]+ { yylval->as() = yytext; return yy::parser::token::TOK_NUMBER; } [A-Za-z_][A-Za-z0-9_]* { yylval->as() = yytext; return yy::parser::token::TOK_IDENTIFIER; } - -<> { - if (indent_helper.hasPendingDedents()) { - indent_helper.consumeDedent(); - return yy::parser::token::TOK_DEDENT; - } - int d; - if ((d = indent_helper.flushDedent()) != 0) return yy::parser::token::TOK_DEDENT; - return yy::parser::token::TOK_EOF; -} - +<> { return yy::parser::token::TOK_EOF; } . { /* ignore other characters */ } diff --git a/src/scanner.hpp b/src/scanner.hpp index 48be22d..f78194e 100644 --- a/src/scanner.hpp +++ b/src/scanner.hpp @@ -5,21 +5,38 @@ #endif #include "parser.hpp" +#include "indent_helper.hpp" #include class Scanner : public yyFlexLexer { public: + IndentHelper indent_helper; Scanner(std::istream &in) : yyFlexLexer(&in), yylval(nullptr) {} int lex(yy::parser::semantic_type *lval) { + if (indent_helper.consumeDedent()) + { + return yy::parser::token::TOK_DEDENT; + } this->yylval = lval; - return yylex(); + int token = yylex(); + + if (token == yy::parser::token::TOK_EOF) + { + int result = indent_helper.processLine(0); + + if (result == -1) + { + return yy::parser::token::TOK_DEDENT; + } + } + + return token; } private: - // implemented by flex virtual int yylex() override; yy::parser::semantic_type *yylval; }; \ No newline at end of file