P4C
The P4 Compiler
Loading...
Searching...
No Matches
parseInput.h
1/*
2Copyright 2013-present Barefoot Networks, Inc.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17#ifndef FRONTENDS_COMMON_PARSEINPUT_H_
18#define FRONTENDS_COMMON_PARSEINPUT_H_
19
20#include "frontends/common/options.h"
21#include "frontends/common/parser_options.h"
22#include "frontends/p4/fromv1.0/converters.h"
23#include "frontends/parsers/parserDriver.h"
24#include "lib/error.h"
25
26namespace P4::IR {
27class P4Program;
28} // namespace P4::IR
29
30namespace P4 {
31
32template <typename Input, typename C = P4V1::Converter>
33static const IR::P4Program *parseV1Program(Input stream, std::string_view sourceFile,
34 unsigned sourceLine,
35 std::optional<DebugHook> debugHook = std::nullopt) {
36 // We load the model before parsing the input file, so that the SourceInfo
37 // in the model comes first.
38 C converter;
39 if (debugHook) converter.addDebugHook(*debugHook, true);
40 converter.loadModel();
41
42 // Parse.
43 const IR::Node *v1 = V1::V1ParserDriver::parse(stream, sourceFile, sourceLine);
44 if (::P4::errorCount() > 0 || v1 == nullptr) return nullptr;
45
46 // Convert to P4-16.
47 if (Log::verbose()) std::cerr << "Converting to P4-16" << std::endl;
48 v1 = v1->apply(converter);
49 if (::P4::errorCount() > 0 || v1 == nullptr) return nullptr;
50 BUG_CHECK(v1->is<IR::P4Program>(), "Conversion returned %1%", v1);
51 return v1->to<IR::P4Program>();
52}
53
62template <typename C = P4V1::Converter>
63const IR::P4Program *parseP4File(const ParserOptions &options) {
64 BUG_CHECK(&options == &P4CContext::get().options(),
65 "Parsing using options that don't match the current "
66 "compiler context");
67
68 const IR::P4Program *result = nullptr;
69 if (options.doNotPreprocess) {
70 auto *file = fopen(options.file.c_str(), "r");
71 if (file == nullptr) {
72 ::P4::error(ErrorType::ERR_NOT_FOUND, "%1%: No such file or directory.", options.file);
73 return nullptr;
74 }
75 result = options.isv1() ? parseV1Program<FILE *, C>(file, options.file.string(), 1,
76 options.getDebugHook())
77 : P4ParserDriver::parse(file, options.file.string());
78 fclose(file);
79 } else {
80 auto preprocessorResult = options.preprocess();
81 if (::P4::errorCount() > 0 || !preprocessorResult.has_value()) {
82 return nullptr;
83 }
84 // Need to assign file here because the parser requires an lvalue.
85 result =
86 options.isv1()
87 ? parseV1Program<FILE *, C>(preprocessorResult.value().get(), options.file.string(),
88 1, options.getDebugHook())
89 : P4ParserDriver::parse(preprocessorResult.value().get(), options.file.string());
90 }
91
92 if (::P4::errorCount() > 0) {
93 ::P4::error(ErrorType::ERR_OVERLIMIT, "%1% errors encountered, aborting compilation",
95 return nullptr;
96 }
97 BUG_CHECK(result != nullptr, "Parsing failed, but we didn't report an error");
98 return result;
99}
100
111const IR::P4Program *parseP4String(const char *sourceFile, unsigned sourceLine,
112 const std::string &input,
113 CompilerOptions::FrontendVersion version);
114const IR::P4Program *parseP4String(const std::string &input,
115 CompilerOptions::FrontendVersion version);
116
117} // namespace P4
118
119#endif /* FRONTENDS_COMMON_PARSEINPUT_H_ */
static P4CContext & get()
Definition parser_options.cpp:535
static const IR::P4Program * parse(std::istream &in, std::string_view sourceFile, unsigned sourceLine=1)
Definition parserDriver.cpp:139
Definition parser_options.h:45
std::filesystem::path file
file to compile (- for stdin)
Definition parser_options.h:74
bool isv1() const
True if we are compiling a P4 v1.0 or v1.1 program.
Definition parser_options.cpp:473
std::optional< ParserOptions::PreprocessorResult > preprocess() const
Returns the output of the preprocessor.
Definition parser_options.cpp:424
bool doNotPreprocess
if true skip preprocess
Definition parser_options.h:80
DebugHook getDebugHook() const
Definition parser_options.cpp:529
static const IR::V1Program * parse(std::istream &in, std::string_view sourceFile, unsigned sourceLine=1)
Definition parserDriver.cpp:291
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24
const IR::P4Program * parseP4String(const char *sourceFile, unsigned sourceLine, const std::string &input, CompilerOptions::FrontendVersion version)
Definition parseInput.cpp:28
const IR::P4Program * parseP4File(const ParserOptions &options)
Definition parseInput.h:63
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition error.h:51
unsigned errorCount()
Definition error.h:35