Shell: Make caller specify the string parsing end condition

Heredocs have a different parse end condition than double-quoted
strings. parse_doublequoted_string_inner would assume that a string
would always end in a double quote, so let's generalize it to
parse_string_inner and have it take a StringEndCondition enum which
specifies how the string terminates.
This commit is contained in:
sin-ack 2021-08-11 21:40:26 +00:00 committed by Ali Mohammad Pur
parent c419b1ade6
commit 4c6a97e757
Notes: sideshowbarker 2024-07-18 07:03:22 +09:00
2 changed files with 16 additions and 6 deletions

View file

@ -1257,7 +1257,7 @@ RefPtr<AST::Node> Parser::parse_string()
if (peek() == '"') { if (peek() == '"') {
consume(); consume();
auto inner = parse_doublequoted_string_inner(); auto inner = parse_string_inner(StringEndCondition::DoubleQuote);
if (!inner) if (!inner)
inner = create<AST::SyntaxError>("Unexpected EOF in string", true); inner = create<AST::SyntaxError>("Unexpected EOF in string", true);
if (!expect('"')) { if (!expect('"')) {
@ -1283,14 +1283,18 @@ RefPtr<AST::Node> Parser::parse_string()
return nullptr; return nullptr;
} }
RefPtr<AST::Node> Parser::parse_doublequoted_string_inner() RefPtr<AST::Node> Parser::parse_string_inner(StringEndCondition condition)
{ {
auto rule_start = push_start(); auto rule_start = push_start();
if (at_end()) if (at_end())
return nullptr; return nullptr;
StringBuilder builder; StringBuilder builder;
while (!at_end() && peek() != '"') { while (!at_end()) {
if (condition == StringEndCondition::DoubleQuote && peek() == '"') {
break;
}
if (peek() == '\\') { if (peek() == '\\') {
consume(); consume();
if (at_end()) { if (at_end()) {
@ -1358,7 +1362,7 @@ RefPtr<AST::Node> Parser::parse_doublequoted_string_inner()
move(string_literal), move(string_literal),
move(node)); // Compose String Node move(node)); // Compose String Node
if (auto string = parse_doublequoted_string_inner()) { if (auto string = parse_string_inner(condition)) {
return create<AST::StringPartCompose>(move(inner), string.release_nonnull()); // Compose Composition Composition return create<AST::StringPartCompose>(move(inner), string.release_nonnull()); // Compose Composition Composition
} }
@ -2083,7 +2087,7 @@ bool Parser::parse_heredoc_entries()
return false; return false;
})); }));
auto expr = parse_doublequoted_string_inner(); auto expr = parse_string_inner(StringEndCondition::Heredoc);
set_end_condition(move(end_condition)); set_end_condition(move(end_condition));
if (found_key) { if (found_key) {

View file

@ -40,6 +40,12 @@ private:
Yes, Yes,
No, No,
}; };
enum class StringEndCondition {
DoubleQuote,
Heredoc,
};
struct SequenceParseResult { struct SequenceParseResult {
NonnullRefPtrVector<AST::Node> entries; NonnullRefPtrVector<AST::Node> entries;
Vector<AST::Position, 1> separator_positions; Vector<AST::Position, 1> separator_positions;
@ -76,7 +82,7 @@ private:
RefPtr<AST::Node> parse_expression(); RefPtr<AST::Node> parse_expression();
RefPtr<AST::Node> parse_string_composite(); RefPtr<AST::Node> parse_string_composite();
RefPtr<AST::Node> parse_string(); RefPtr<AST::Node> parse_string();
RefPtr<AST::Node> parse_doublequoted_string_inner(); RefPtr<AST::Node> parse_string_inner(StringEndCondition);
RefPtr<AST::Node> parse_variable(); RefPtr<AST::Node> parse_variable();
RefPtr<AST::Node> parse_variable_ref(); RefPtr<AST::Node> parse_variable_ref();
RefPtr<AST::Node> parse_slice(); RefPtr<AST::Node> parse_slice();