VapourSynth-llvmexpr
Loading...
Searching...
No Matches
infix2postfix::AnalysisEngine Class Reference

#include <llvmexpr/frontend/infix2postfix/AnalysisEngine.hpp>

Public Member Functions

 AnalysisEngine (const std::vector< Token > &tokens, Mode mode, int num_inputs, int num_intermediate_inputs, const std::vector< LineMapping > &line_map, int library_line_count=0)
 ~AnalysisEngine ()
 AnalysisEngine (const AnalysisEngine &)=delete
AnalysisEngineoperator= (const AnalysisEngine &)=delete
 AnalysisEngine (AnalysisEngine &&)=delete
AnalysisEngineoperator= (AnalysisEngine &&)=delete
bool runAnalysis ()
std::string generateCode ()
const ProgramgetAST () const
ProgramgetAST ()
const std::vector< Diagnostic > & getDiagnostics () const
bool hasErrors () const
std::string formatDiagnostics () const

Detailed Description

Definition at line 49 of file AnalysisEngine.hpp.

Constructor & Destructor Documentation

◆ AnalysisEngine() [1/3]

infix2postfix::AnalysisEngine::AnalysisEngine ( const std::vector< Token > & tokens,
Mode mode,
int num_inputs,
int num_intermediate_inputs,
const std::vector< LineMapping > & line_map,
int library_line_count = 0 )

Definition at line 31 of file AnalysisEngine.cpp.

35 : tokens(tokens), mode(mode), num_inputs(num_inputs),
36 num_intermediate_inputs(num_intermediate_inputs), line_map(line_map),
37 library_line_count(library_line_count) {}

Referenced by AnalysisEngine(), AnalysisEngine(), operator=(), and operator=().

◆ ~AnalysisEngine()

infix2postfix::AnalysisEngine::~AnalysisEngine ( )
default

◆ AnalysisEngine() [2/3]

infix2postfix::AnalysisEngine::AnalysisEngine ( const AnalysisEngine & )
delete

References AnalysisEngine().

◆ AnalysisEngine() [3/3]

infix2postfix::AnalysisEngine::AnalysisEngine ( AnalysisEngine && )
delete

References AnalysisEngine().

Member Function Documentation

◆ formatDiagnostics()

std::string infix2postfix::AnalysisEngine::formatDiagnostics ( ) const
nodiscard

Definition at line 91 of file AnalysisEngine.cpp.

91 {
92 if (diagnostics.empty()) {
93 return "";
94 }
95
96 std::string result;
97 int error_count = 0;
98 int warning_count = 0;
99
100 for (const auto& diag : diagnostics) {
101 if (diag.severity == DiagnosticSeverity::Error) {
102 error_count++;
103 } else {
104 warning_count++;
105 }
106
107 if (!result.empty()) {
108 result += "\n";
109 }
110 std::string severity_name = std::string(enum_name(diag.severity));
111
112 const LineMapping* mapping = nullptr;
113 auto it = std::ranges::find_if(line_map, [&](const auto& m) {
114 return m.preprocessed_line == diag.range.start.line;
115 });
116 if (it != line_map.end()) {
117 mapping = &(*it);
118 }
119
120 Range range = diag.range;
121 std::string message = diag.message;
122
123 if (mapping != nullptr) {
124 range.start.line = mapping->original_line;
125 range.end.line = mapping->original_line;
126
127 if (!mapping->expansions.empty()) {
128 std::string expansion_trace;
129 std::vector<const MacroExpansion*> containing_expansions;
130
131 for (const auto& expansion : mapping->expansions) {
132 if (diag.range.start.column + 1 >=
133 expansion.preprocessed_start_column &&
134 diag.range.end.column <
135 expansion.preprocessed_end_column) {
136 containing_expansions.push_back(&expansion);
137 }
138 }
139
140 std::ranges::sort(containing_expansions,
141 [](const auto* a, const auto* b) {
142 return (a->preprocessed_end_column -
143 a->preprocessed_start_column) <
144 (b->preprocessed_end_column -
145 b->preprocessed_start_column);
146 });
147
148 for (const auto* expansion : containing_expansions) {
149 expansion_trace += std::format(
150 "\n note: in expansion of macro '{}' from {}:{}",
151 expansion->macro_name, mapping->original_line,
152 expansion->original_column);
153 }
154 message += expansion_trace;
155 }
156 }
157
158 result += std::format("{} - {}: {}", range.to_string(), severity_name,
159 message);
160 }
161
162 std::string summary;
163 if (error_count > 0 && warning_count > 0) {
164 summary = std::format("\nFound {} error(s) and {} warning(s).",
165 error_count, warning_count);
166 } else if (error_count > 0) {
167 summary = std::format("\nFound {} error(s).", error_count);
168 } else if (warning_count > 0) {
169 summary = std::format("\nFound {} warning(s).", warning_count);
170 }
171
172 result += summary;
173 return result;
174}
consteval std::string_view enum_name()
Definition EnumName.hpp:57

References infix2postfix::Range::end, enum_name(), infix2postfix::Error, infix2postfix::LineMapping::expansions, infix2postfix::SourceLocation::line, infix2postfix::LineMapping::original_line, infix2postfix::Range::start, and infix2postfix::Range::to_string().

Referenced by convert_infix_to_postfix(), and main().

◆ generateCode()

std::string infix2postfix::AnalysisEngine::generateCode ( )

Definition at line 69 of file AnalysisEngine.cpp.

69 {
70 if (!ast || !semantic_analyzer) {
71 throw std::runtime_error(
72 "Cannot generate code: analysis not run or failed");
73 }
74
75 if (hasErrors()) {
76 throw std::runtime_error(
77 "Cannot generate code: semantic analysis had errors");
78 }
79
80 CodeGenerator code_generator(mode, num_inputs, num_intermediate_inputs);
81
82 return code_generator.generate(ast.get());
83}

References infix2postfix::CodeGenerator::generate(), and hasErrors().

Referenced by convert_infix_to_postfix(), and main().

◆ getAST() [1/2]

Program * infix2postfix::AnalysisEngine::getAST ( )
inline

Definition at line 67 of file AnalysisEngine.hpp.

67{ return ast.get(); }

◆ getAST() [2/2]

const Program * infix2postfix::AnalysisEngine::getAST ( ) const
inlinenodiscard

Definition at line 66 of file AnalysisEngine.hpp.

66{ return ast.get(); }

Referenced by main().

◆ getDiagnostics()

const std::vector< Diagnostic > & infix2postfix::AnalysisEngine::getDiagnostics ( ) const
inlinenodiscard

Definition at line 69 of file AnalysisEngine.hpp.

69 {
70 return diagnostics;
71 }

◆ hasErrors()

bool infix2postfix::AnalysisEngine::hasErrors ( ) const
nodiscard

Definition at line 85 of file AnalysisEngine.cpp.

85 {
86 return std::ranges::any_of(diagnostics, [](const auto& diag) {
87 return diag.severity == DiagnosticSeverity::Error;
88 });
89}

References infix2postfix::Error.

Referenced by generateCode(), and runAnalysis().

◆ operator=() [1/2]

AnalysisEngine & infix2postfix::AnalysisEngine::operator= ( AnalysisEngine && )
delete

References AnalysisEngine().

◆ operator=() [2/2]

AnalysisEngine & infix2postfix::AnalysisEngine::operator= ( const AnalysisEngine & )
delete

References AnalysisEngine().

◆ runAnalysis()

bool infix2postfix::AnalysisEngine::runAnalysis ( )

Definition at line 41 of file AnalysisEngine.cpp.

41 {
42 diagnostics.clear();
43
44 Parser parser(tokens);
45 auto parse_result = parser.parse();
46 ast = std::move(parse_result.ast);
47
48 std::ranges::transform(parse_result.errors, std::back_inserter(diagnostics),
49 [](const auto& error) {
50 return Diagnostic(DiagnosticSeverity::Error,
51 error.message, error.range);
52 });
53
54 if (!ast || hasErrors()) {
55 return false;
56 }
57
58 semantic_analyzer = std::make_unique<SemanticAnalyzer>(
59 mode, num_inputs, num_intermediate_inputs, library_line_count);
60 semantic_analyzer->analyze(ast.get());
61
62 const auto& semantic_diagnostics = semantic_analyzer->getDiagnostics();
63 diagnostics.insert(diagnostics.end(), semantic_diagnostics.begin(),
64 semantic_diagnostics.end());
65
66 return !hasErrors();
67}

References hasErrors(), and infix2postfix::Parser::parse().

Referenced by convert_infix_to_postfix(), and main().


The documentation for this class was generated from the following files: