new interface

This commit is contained in:
bronku 2025-12-02 13:57:45 +01:00
parent b263b1e8b4
commit 5c9abff73f
22 changed files with 75 additions and 34 deletions

View file

@ -17,18 +17,18 @@ void dump_tokens(Scanner &scanner)
int tok = scanner.lex(&lval); int tok = scanner.lex(&lval);
if (tok == Parser::token::TOK_EOF) if (tok == Parser::token::TOK_EOF)
{ {
std::cout << Parser::symbol_name(static_cast<kind>(tok)); // std::cout << Parser::symbol_name(static_cast<kind>(tok));
break; break;
} }
std::cout << Parser::symbol_name(static_cast<kind>(tok)); // std::cout << Parser::symbol_name(static_cast<kind>(tok));
if (tok == Parser::token::TOK_IDENTIFIER || tok == Parser::token::TOK_NUMBER || tok == Parser::token::TOK_STRING) if (tok == Parser::token::TOK_IDENTIFIER || tok == Parser::token::TOK_NUMBER || tok == Parser::token::TOK_STRING)
{ {
std::cout << " " << lval.as<std::string>(); // std::cout << " " << lval.as<std::string>();
} }
std::cout << "\n"; // std::cout << "\n";
} }
} }
@ -39,6 +39,8 @@ int main(int argc, char *argv[])
bool token_dump = false; bool token_dump = false;
bool ast_dump = false; bool ast_dump = false;
bool write_ruby = true;
bool no_parsing = false;
for (int i = 1; i < argc; ++i) for (int i = 1; i < argc; ++i)
{ {
@ -56,10 +58,22 @@ int main(int argc, char *argv[])
{ {
ast_dump = true; ast_dump = true;
} }
else if (arg == "--no-output")
{
write_ruby = false;
}
else if (arg == "--no-parsing")
{
no_parsing = true;
}
} }
Scanner scanner(*input_stream); Scanner scanner(*input_stream);
if (token_dump) if (token_dump)
{
scanner.print_results = true;
}
if (no_parsing)
{ {
dump_tokens(scanner); dump_tokens(scanner);
return 0; return 0;
@ -72,9 +86,11 @@ int main(int argc, char *argv[])
if (ast_dump) if (ast_dump)
{ {
std::cout << ast_root->dump(); std::cout << ast_root->dump();
return 0;
} }
if (write_ruby)
{
RubyGenerator generator; RubyGenerator generator;
std::cout << generator.generate(*ast_root); std::cout << generator.generate(*ast_root);
}
} }

View file

@ -14,6 +14,7 @@ class Scanner : public yyFlexLexer
bool last_was_newline = true; bool last_was_newline = true;
public: public:
bool print_results = false;
IndentStack indent_stack; IndentStack indent_stack;
Scanner(std::istream &in) : yyFlexLexer(&in), yylval(nullptr) {} Scanner(std::istream &in) : yyFlexLexer(&in), yylval(nullptr) {}
@ -24,13 +25,15 @@ public:
if (eof_emitted) if (eof_emitted)
{ {
// std::cout << "lex: 0\n";
return 0; return 0;
} }
if (indent_stack.popDedent()) if (indent_stack.popDedent())
{ {
// std::cout << "lex: dedent\n"; if (print_results)
{
std::cout << "DEDENT\n";
}
return yy::parser::token::TOK_DEDENT; return yy::parser::token::TOK_DEDENT;
} }
@ -39,18 +42,23 @@ public:
if (token == yy::parser::token::TOK_EOF) if (token == yy::parser::token::TOK_EOF)
{ {
// Emit synthetic NEWLINE if needed
if (!last_was_newline) if (!last_was_newline)
{ {
last_was_newline = true; last_was_newline = true;
// std::cout << "lex: newline\n"; if (print_results)
{
std::cout << "NEWLINE\n";
}
return yy::parser::token::TOK_NEWLINE; return yy::parser::token::TOK_NEWLINE;
} }
auto result = indent_stack.closeBlock(); auto result = indent_stack.closeBlock();
if (result == IndentAction::Dedent) if (result == IndentAction::Dedent)
{ {
// std::cout << "lex: dedent\n"; if (print_results)
{
std::cout << "DEDENT\n";
}
return yy::parser::token::TOK_DEDENT; return yy::parser::token::TOK_DEDENT;
} }
@ -59,7 +67,24 @@ public:
last_was_newline = (token == yy::parser::token::TOK_NEWLINE); last_was_newline = (token == yy::parser::token::TOK_NEWLINE);
// std::cout << "lex: " << Parser::symbol_name(static_cast<kind>(token)) << '\n'; if (print_results)
{
std::cout << Parser::symbol_name(static_cast<kind>(token));
}
if (token == Parser::token::TOK_IDENTIFIER || token == Parser::token::TOK_NUMBER || token == Parser::token::TOK_STRING)
{
if (print_results)
{
std::cout << " " << lval->as<std::string>();
}
}
if (print_results)
{
std::cout << "\n";
}
return token; return token;
} }

View file

@ -6,7 +6,7 @@ for test in lexer/*.in; do
name=$(basename "$test" .in) name=$(basename "$test" .in)
echo "Testing lexer/$name..." echo "Testing lexer/$name..."
if ! ../build/py2rb --dump-tokens < "$test" | diff - "lexer/${name}.out"; then if ! ../build/py2rb --dump-tokens --no-output --no-parsing < "$test" | diff - "lexer/${name}.out"; then
echo "FAILED: lexer/$name" echo "FAILED: lexer/$name"
exit 1 exit 1
fi fi
@ -19,7 +19,7 @@ for test in parser/*.in; do
name=$(basename "$test" .in) name=$(basename "$test" .in)
echo "Testing parser/$name..." echo "Testing parser/$name..."
if ! ../build/py2rb --dump-ast < "$test" | diff - "parser/${name}.out"; then if ! ../build/py2rb --dump-ast --no-output < "$test" | diff - "parser/${name}.out"; then
echo "FAILED: parser/$name" echo "FAILED: parser/$name"
exit 1 exit 1
fi fi