newline at eof fix

This commit is contained in:
bronku 2025-11-27 17:15:29 +01:00
parent 922213d9c6
commit f0f71075f1
2 changed files with 38 additions and 26 deletions

View file

@ -69,7 +69,7 @@ stmt_list:
;
stmt:
expr { $$ = std::make_unique<ExprStmt>(std::move($1)); }
expr NEWLINE { $$ = std::make_unique<ExprStmt>(std::move($1)); }
;
expr:

View file

@ -11,6 +11,7 @@
class Scanner : public yyFlexLexer
{
bool eof_emitted = false;
bool last_was_newline = true;
public:
IndentStack indent_stack;
@ -18,40 +19,51 @@ public:
int lex(yy::parser::semantic_type *lval)
{
if (indent_stack.popDedent())
{
return yy::parser::token::TOK_DEDENT;
}
this->yylval = lval;
int token = yylex();
// std::cout << "lex: " << yy::parser::symbol_name(static_cast<yy::parser::symbol_kind_type>(token)) << '\n';
if (token == yy::parser::token::TOK_EOF)
{
auto result = indent_stack.closeBlock();
if (result == IndentAction::Dedent)
{
return yy::parser::token::TOK_DEDENT;
}
}
if (token != yy::parser::token::TOK_EOF)
{
return token;
}
using Parser = yy::parser;
using kind = Parser::symbol_kind_type;
if (eof_emitted)
{
//std::cout << "lex: 0\n";
return 0;
}
eof_emitted = true;
if (indent_stack.popDedent())
{
//std::cout << "lex: dedent\n";
return yy::parser::token::TOK_DEDENT;
}
this->yylval = lval;
int token = yylex();
if (token == yy::parser::token::TOK_EOF)
{
// Emit synthetic NEWLINE if needed
if (!last_was_newline)
{
last_was_newline = true;
//std::cout << "lex: newline\n";
return yy::parser::token::TOK_NEWLINE;
}
auto result = indent_stack.closeBlock();
if (result == IndentAction::Dedent)
{
//std::cout << "lex: dedent\n";
return yy::parser::token::TOK_DEDENT;
}
eof_emitted = true;
}
last_was_newline = (token == yy::parser::token::TOK_NEWLINE);
//std::cout << "lex: " << Parser::symbol_name(static_cast<kind>(token)) << '\n';
return token;
}
private:
virtual int yylex() override;
yy::parser::semantic_type *yylval;
};
};