indent fix

This commit is contained in:
bronku 2025-11-25 15:36:51 +01:00
parent 5062a9b588
commit 4def48d206
3 changed files with 37 additions and 50 deletions

View file

@ -13,17 +13,17 @@ public:
{ {
int current = indent_stack.top(); int current = indent_stack.top();
if (spaces == current)
{
return 0;
}
if (spaces > current) if (spaces > current)
{ {
indent_stack.push(spaces); indent_stack.push(spaces);
return 1; return 1;
} }
if (spaces == current)
{
return 0;
}
pending_dedents = 0; pending_dedents = 0;
while (indent_stack.top() > spaces) while (indent_stack.top() > spaces)
{ {
@ -31,35 +31,23 @@ public:
pending_dedents++; 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) if (pending_dedents > 0)
{ {
pending_dedents--; pending_dedents--;
return -1;
} }
return 0;
} }
int flushAllDedents() // returns false on failure
bool consumeDedent()
{ {
int total_dedents = 0; if (pending_dedents <= 0)
while (indent_stack.size() > 1)
{ {
indent_stack.pop(); return false;
total_dedents++;
} }
return total_dedents; pending_dedents--;
return true;
} }
}; };

View file

@ -7,18 +7,13 @@
#include "scanner.hpp" #include "scanner.hpp"
#include "indent_helper.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]* { ^[ \t]* {
if (!at_line_start) {
REJECT;
}
at_line_start = false;
int spaces = 0; int spaces = 0;
for (int i = 0; i < yyleng; i++) for (int i = 0; i < yyleng; i++)
spaces += (yytext[i] == '\t') ? 8 : 1; spaces += (yytext[i] == '\t') ? 8 : 1;
@ -28,10 +23,7 @@ bool at_line_start = true;
if (result < 0) return yy::parser::token::TOK_DEDENT; if (result < 0) return yy::parser::token::TOK_DEDENT;
} }
\n { \n { return yy::parser::token::TOK_NEWLINE; }
at_line_start = true;
return yy::parser::token::TOK_NEWLINE;
}
def { return yy::parser::token::TOK_KW_DEF; } def { return yy::parser::token::TOK_KW_DEF; }
if { return yy::parser::token::TOK_KW_IF; } if { return yy::parser::token::TOK_KW_IF; }
@ -54,15 +46,5 @@ in { return yy::parser::token::TOK_KW_IN; }
[0-9]+ { yylval->as<std::string>() = yytext; return yy::parser::token::TOK_NUMBER; } [0-9]+ { yylval->as<std::string>() = yytext; return yy::parser::token::TOK_NUMBER; }
[A-Za-z_][A-Za-z0-9_]* { yylval->as<std::string>() = yytext; return yy::parser::token::TOK_IDENTIFIER; } [A-Za-z_][A-Za-z0-9_]* { yylval->as<std::string>() = yytext; return yy::parser::token::TOK_IDENTIFIER; }
<<EOF>> { return yy::parser::token::TOK_EOF; }
<<EOF>> {
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;
}
. { /* ignore other characters */ } . { /* ignore other characters */ }

View file

@ -5,21 +5,38 @@
#endif #endif
#include "parser.hpp" #include "parser.hpp"
#include "indent_helper.hpp"
#include <string> #include <string>
class Scanner : public yyFlexLexer class Scanner : public yyFlexLexer
{ {
public: public:
IndentHelper indent_helper;
Scanner(std::istream &in) : yyFlexLexer(&in), yylval(nullptr) {} Scanner(std::istream &in) : yyFlexLexer(&in), yylval(nullptr) {}
int lex(yy::parser::semantic_type *lval) int lex(yy::parser::semantic_type *lval)
{ {
if (indent_helper.consumeDedent())
{
return yy::parser::token::TOK_DEDENT;
}
this->yylval = lval; 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: private:
// implemented by flex
virtual int yylex() override; virtual int yylex() override;
yy::parser::semantic_type *yylval; yy::parser::semantic_type *yylval;
}; };