6#include <unordered_map>
7#include <unordered_set>
11#include "gsl/pointers"
68 Parser(gsl::not_null<const TextFormatter *> format, std::vector<Token> tokens)
69 : format_{format}, tokens_{std::move(tokens)}
82 Parser(gsl::not_null<const TextFormatter *> format, std::vector<Token> tokens,
const CParserContext *context)
83 : format_{format}, tokens_{std::move(tokens)}, context_{context}
316 return scan_warnings_;
329 return ambiguous_defines_;
341 return defined_names_;
352 void seed_symbols(
const std::unordered_map<std::string, std::int64_t> &symbols)
354 for (
const auto &[
name, value] : symbols) {
355 defined_values_[
name] = value;
356 defined_names_.insert(
name);
368 void seed_values(
const std::unordered_map<std::string, std::int64_t> &symbols)
370 for (
const auto &[
name, value] : symbols) {
371 defined_values_[
name] = value;
381 enum class CondState : std::uint8_t { active, skipping, both };
389 struct ConditionalFrame {
395 [[nodiscard]]
const Token &peek()
const;
396 [[nodiscard]]
const Token &peek_next()
const;
397 const Token &advance();
398 [[nodiscard]]
bool is_at_end()
const;
399 [[nodiscard]]
bool check(
TokenType type)
const;
402 void skip_to_next_line();
403 [[nodiscard]]
bool is_at_line_end()
const;
408 [[nodiscard]] CondState effective_cond_state()
const;
409 bool try_handle_conditional();
410 [[nodiscard]] std::pair<CondState, bool> classify_ifdef(
bool negated);
411 [[nodiscard]] std::pair<CondState, bool> classify_if_expression();
412 [[nodiscard]] std::optional<std::vector<Token>> substitute_defined_operators(
const std::vector<Token> &expr)
const;
414 [[nodiscard]] ChainableResult<DefineStatement> parse_define();
415 void record_define(DefineStatement statement, std::vector<DefineStatement> &out);
416 [[nodiscard]] ChainableResult<EnumDeclaration> parse_enum();
417 [[nodiscard]] ChainableResult<EnumMember> parse_enum_member(std::int64_t &counter);
421 struct DefineParseOutcome {
422 std::optional<DefineStatement> statement;
423 std::optional<SkippedConstruct> skipped;
425 [[nodiscard]] DefineParseOutcome parse_define_tolerant();
426 [[nodiscard]] std::optional<TolerantEnum> parse_enum_tolerant();
427 [[nodiscard]] TolerantEnumMember parse_enum_member_tolerant(std::int64_t &counter,
bool &counter_valid);
428 [[nodiscard]] std::vector<IndexedArrayEntry> parse_indexed_entries(
const std::vector<Token> &brace_contents);
429 [[nodiscard]] std::vector<Token> collect_expression_tokens();
430 [[nodiscard]] std::vector<Token> collect_enum_value_tokens();
431 [[nodiscard]] ChainableResult<std::int64_t> evaluate_expression(
const std::vector<Token> &expr_tokens);
434 [[nodiscard]] std::vector<Token> to_postfix(
const std::vector<Token> &expr_tokens);
435 [[nodiscard]] ChainableResult<std::int64_t> evaluate_postfix(
const std::vector<Token> &postfix);
436 [[nodiscard]]
int operator_precedence(
TokenType type)
const;
437 [[nodiscard]]
bool is_left_associative(
TokenType type)
const;
438 [[nodiscard]]
bool is_operator(
TokenType type)
const;
439 [[nodiscard]]
bool is_unary_operator(
TokenType type)
const;
441 [[nodiscard]] FormattableError make_error(SourcePosition pos, std::string message)
const;
443 const TextFormatter *format_;
444 std::vector<Token> tokens_;
445 std::size_t current_{0};
446 std::unordered_map<std::string, std::int64_t> defined_values_{{
"UCHAR_MAX", 255}};
447 std::unordered_set<std::string> defined_names_;
448 std::vector<ConditionalFrame> cond_stack_;
449 std::vector<std::string> scan_warnings_;
450 std::unordered_set<std::string> ambiguous_defines_;
451 const CParserContext *context_{
nullptr};
Context object providing rich error formatting for C/C++ parsing.
A result type that maintains a chainable sequence of errors for debugging and error reporting.
Parser for C preprocessor constructs.
const std::unordered_set< std::string > & ambiguous_defines() const
Returns names whose definitions conflicted in an undecidable conditional branch.
Parser(gsl::not_null< const TextFormatter * > format, std::vector< Token > tokens, const CParserContext *context)
Constructs a parser with a context for rich error formatting.
ChainableResult< std::vector< ArrayDeclaration > > parse_pointer_arrays()
Parses all pointer array declarations from the token stream.
ChainableResult< std::vector< EnumDeclaration > > parse_enums()
Parses all enum declarations from the token stream.
ChainableResult< std::vector< DefineStatement > > parse_defines()
Parses all #define statements from the token stream.
void seed_symbols(const std::unordered_map< std::string, std::int64_t > &symbols)
Seeds the symbol table with externally known macro values before scanning.
ChainableResult< std::vector< IncbinDeclaration > > parse_incbin_arrays()
Parses INCBIN array declarations from the token stream.
const std::unordered_set< std::string > & defined_names() const
Returns the set of macro names seen as defined so far.
ChainableResult< std::vector< StructVariableDeclaration > > parse_struct_variables()
Parses struct variable declarations from the token stream.
ChainableResult< std::vector< StructInitializerDeclaration > > parse_struct_initializers()
Parses struct variable declarations with their designated initializer fields.
const std::vector< std::string > & scan_warnings() const
Returns warnings accumulated while scanning conditionals and defines.
TolerantEnumScan parse_enums_tolerant()
Parses all enum declarations, tolerating individual member evaluation failures.
Parser(gsl::not_null< const TextFormatter * > format, std::vector< Token > tokens)
Constructs a parser for the given token stream.
ChainableResult< std::vector< StructDefinition > > parse_struct_definitions()
Parses struct type definitions from the token stream.
ChainableResult< std::vector< IndexedArrayDeclaration > > parse_indexed_arrays()
Parses array declarations that use designated (indexed) initializers.
void seed_values(const std::unordered_map< std::string, std::int64_t > &symbols)
Seeds only expression values without marking their names as preprocessor-defined.
TolerantDefineScan parse_defines_tolerant()
Parses all #define statements, tolerating individual evaluation failures.
ChainableResult< std::vector< FunctionDefinition > > parse_functions()
Parses function definitions from the token stream.
TokenType
Enumeration of token types recognized by the C parser lexer.
The result of a tolerant #define scan.
The result of a tolerant enum scan.