Преглед на файлове

Shell: Correctly handle commands after heredoc contents

Previously we did not emit a newline after the ending heredoc key, which
wreaked havoc on the parser logic, leading to parse errors.
Ali Mohammad Pur преди 2 години
родител
ревизия
7b031138fc
променени са 4 файла, в които са добавени 11 реда и са изтрити 1 реда
  1. 5 1
      Userland/Shell/PosixLexer.cpp
  2. 2 0
      Userland/Shell/PosixLexer.h
  3. 3 0
      Userland/Shell/PosixParser.cpp
  4. 1 0
      Userland/Shell/PosixParser.h

+ 5 - 1
Userland/Shell/PosixLexer.cpp

@@ -581,9 +581,13 @@ ErrorOr<Lexer::ReductionResult> Lexer::reduce_start()
         m_state.on_new_line = true;
 
         m_state.buffer.clear();
+        m_state.position.start_offset = m_state.position.end_offset;
+        m_state.position.start_line = m_state.position.end_line;
+
+        Vector<Token> tokens { move(token), Token::newline() };
 
         return ReductionResult {
-            .tokens = { move(token) },
+            .tokens = move(tokens),
             .next_reduction = Reduction::Start,
         };
     }

+ 2 - 0
Userland/Shell/PosixLexer.h

@@ -321,6 +321,8 @@ struct Token {
             return Token::Type::Great;
         if (name == "<"sv)
             return Token::Type::Less;
+        if (name == "\n"sv)
+            return Token::Type::Newline;
 
         return {};
     }

+ 3 - 0
Userland/Shell/PosixParser.cpp

@@ -698,6 +698,9 @@ ErrorOr<RefPtr<AST::Node>> Parser::parse_list()
 
 ErrorOr<RefPtr<AST::Node>> Parser::parse_and_or()
 {
+    while (peek().type == Token::Type::Newline)
+        skip();
+
     auto node = TRY(parse_pipeline());
     if (!node)
         return RefPtr<AST::Node> {};

+ 1 - 0
Userland/Shell/PosixParser.h

@@ -54,6 +54,7 @@ private:
     {
         if (eof())
             return;
+        handle_heredoc_contents();
         m_token_index++;
     }
     bool eof() const