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;
} }
RubyGenerator generator; if (write_ruby)
std::cout << generator.generate(*ast_root); {
RubyGenerator generator;
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

@ -12,4 +12,4 @@ IDENTIFIER y
MINUS MINUS
IDENTIFIER z IDENTIFIER z
NEWLINE NEWLINE
EOF EOF

View file

@ -28,4 +28,4 @@ R_PAREN
NEWLINE NEWLINE
DEDENT DEDENT
DEDENT DEDENT
EOF EOF

View file

@ -70,4 +70,4 @@ KW_RETURN
IDENTIFIER result IDENTIFIER result
NEWLINE NEWLINE
DEDENT DEDENT
EOF EOF

View file

@ -31,4 +31,4 @@ COLON
DOT DOT
SEMICOLON SEMICOLON
NEWLINE NEWLINE
EOF EOF

View file

@ -10,4 +10,4 @@ NEWLINE
STRING 'test' STRING 'test'
STRING "escaped\"quote" STRING "escaped\"quote"
NEWLINE NEWLINE
EOF EOF

View file

@ -48,4 +48,4 @@ COMMA
NUMBER 15 NUMBER 15
R_PAREN R_PAREN
NEWLINE NEWLINE
EOF EOF

View file

@ -18,4 +18,4 @@ IDENTIFIER very_long_variable_name_123
ASSIGN ASSIGN
STRING "test" STRING "test"
NEWLINE NEWLINE
EOF EOF

View file

@ -16,4 +16,4 @@ NEWLINE
KW_NOT KW_NOT
IDENTIFIER flag IDENTIFIER flag
NEWLINE NEWLINE
EOF EOF

View file

@ -10,4 +10,4 @@ INDENT
KW_PASS KW_PASS
NEWLINE NEWLINE
DEDENT DEDENT
EOF EOF

View file

@ -10,4 +10,4 @@ IDENTIFIER e
RSHIFT RSHIFT
IDENTIFIER f IDENTIFIER f
NEWLINE NEWLINE
EOF EOF

View file

@ -38,4 +38,4 @@ IDENTIFIER g
RSHIFT_ASSIGN RSHIFT_ASSIGN
NUMBER 10 NUMBER 10
NEWLINE NEWLINE
EOF EOF

View file

@ -16,4 +16,4 @@ L_BRACKET
IDENTIFIER index IDENTIFIER index
R_BRACKET R_BRACKET
NEWLINE NEWLINE
EOF EOF

View file

@ -38,4 +38,4 @@ COMMA
NUMBER 3 NUMBER 3
R_BRACE R_BRACE
NEWLINE NEWLINE
EOF EOF

View file

@ -4,4 +4,4 @@ STRING 'quote\'test'
NEWLINE NEWLINE
STRING "unicode ☃ snowman" STRING "unicode ☃ snowman"
NEWLINE NEWLINE
EOF EOF

View file

@ -13,4 +13,4 @@ INDENT
KW_PASS KW_PASS
NEWLINE NEWLINE
DEDENT DEDENT
EOF EOF

View file

@ -12,4 +12,4 @@ NUMBER 5
BIT_XOR BIT_XOR
NUMBER 6 NUMBER 6
NEWLINE NEWLINE
EOF EOF

View file

@ -10,4 +10,4 @@ IDENTIFIER s3
ASSIGN ASSIGN
STRING "mixed 'quotes' \"inside\"" STRING "mixed 'quotes' \"inside\""
NEWLINE NEWLINE
EOF EOF

View file

@ -26,4 +26,4 @@ NUMBER 7
R_BRACE R_BRACE
R_BRACKET R_BRACKET
NEWLINE NEWLINE
EOF EOF

View file

@ -167,4 +167,4 @@ COMMA
NUMBER 15 NUMBER 15
R_PAREN R_PAREN
NEWLINE NEWLINE
EOF EOF

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