123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- /*
- * Copyright (c) 2022, Ali Mohammad Pur <mpfard@serenityos.org>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
- #pragma once
- #include <Shell/AST.h>
- #include <Shell/PosixLexer.h>
- namespace Shell::Posix {
- class Parser {
- public:
- Parser(StringView input, bool interactive = false)
- : m_lexer(input)
- , m_in_interactive_mode(interactive)
- , m_eof_token(Token::eof())
- {
- fill_token_buffer();
- }
- RefPtr<AST::Node> parse();
- RefPtr<AST::Node> parse_word_list();
- struct Error {
- DeprecatedString message;
- Optional<AST::Position> position;
- };
- auto& errors() const { return m_errors; }
- private:
- Optional<Token> next_expanded_token();
- Vector<Token> perform_expansions(Vector<Token> tokens);
- void fill_token_buffer();
- Token const& peek() const
- {
- if (eof())
- return m_eof_token;
- return m_token_buffer[m_token_index];
- }
- Token const& consume()
- {
- if (eof())
- return m_eof_token;
- return m_token_buffer[m_token_index++];
- }
- void skip()
- {
- if (eof())
- return;
- m_token_index++;
- }
- bool eof() const
- {
- return m_token_index == m_token_buffer.size() || m_token_buffer[m_token_index].type == Token::Type::Eof;
- }
- struct CaseItemsResult {
- Vector<AST::Position> pipe_positions;
- NonnullRefPtrVector<AST::Node> nodes;
- };
- RefPtr<AST::Node> parse_complete_command();
- RefPtr<AST::Node> parse_list();
- RefPtr<AST::Node> parse_and_or();
- RefPtr<AST::Node> parse_pipeline();
- RefPtr<AST::Node> parse_pipe_sequence();
- RefPtr<AST::Node> parse_command();
- RefPtr<AST::Node> parse_compound_command();
- RefPtr<AST::Node> parse_subshell();
- RefPtr<AST::Node> parse_compound_list();
- RefPtr<AST::Node> parse_term();
- RefPtr<AST::Node> parse_for_clause();
- RefPtr<AST::Node> parse_case_clause();
- CaseItemsResult parse_case_list();
- RefPtr<AST::Node> parse_if_clause();
- RefPtr<AST::Node> parse_while_clause();
- RefPtr<AST::Node> parse_until_clause();
- RefPtr<AST::Node> parse_function_definition();
- RefPtr<AST::Node> parse_function_body();
- RefPtr<AST::Node> parse_brace_group();
- RefPtr<AST::Node> parse_do_group();
- RefPtr<AST::Node> parse_simple_command();
- RefPtr<AST::Node> parse_prefix();
- RefPtr<AST::Node> parse_suffix();
- RefPtr<AST::Node> parse_io_redirect();
- RefPtr<AST::Node> parse_redirect_list();
- RefPtr<AST::Node> parse_io_file(AST::Position, Optional<int> fd);
- RefPtr<AST::Node> parse_io_here(AST::Position, Optional<int> fd);
- RefPtr<AST::Node> parse_word();
- template<typename... Ts>
- void error(Token const& token, CheckedFormatString<Ts...> fmt, Ts&&... args)
- {
- m_errors.append(Error {
- DeprecatedString::formatted(fmt.view(), forward<Ts>(args)...),
- token.position,
- });
- }
- Lexer m_lexer;
- bool m_in_interactive_mode { false };
- Vector<Token, 2> m_token_buffer;
- size_t m_token_index { 0 };
- Vector<Token> m_previous_token_buffer;
- Vector<Error> m_errors;
- Token m_eof_token;
- bool m_disallow_command_prefix { true };
- };
- }
|