P4C
The P4 Compiler
Loading...
Searching...
No Matches
parseInput.h
1/*
2 * SPDX-FileCopyrightText: 2013 Barefoot Networks, Inc.
3 * Copyright 2013-present Barefoot Networks, Inc.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8#ifndef FRONTENDS_COMMON_PARSEINPUT_H_
9#define FRONTENDS_COMMON_PARSEINPUT_H_
10
11#include "frontends/common/options.h"
12#include "frontends/common/parser_options.h"
13#ifdef SUPPORT_P4_14
14#include "frontends/p4-14/fromv1.0/converters.h"
15#endif
16#include "frontends/parsers/parserDriver.h"
17#include "lib/error.h"
18
19namespace P4::IR {
20class P4Program;
21} // namespace P4::IR
22
23namespace P4 {
24
25#ifdef SUPPORT_P4_14
26template <typename Input, typename C = P4V1::Converter>
27static const IR::P4Program *parseV1Program(Input stream, std::string_view sourceFile,
28 unsigned sourceLine,
29 std::optional<DebugHook> debugHook = std::nullopt) {
30 // We load the model before parsing the input file, so that the SourceInfo
31 // in the model comes first.
32 C converter;
33 if (debugHook) converter.addDebugHook(*debugHook, true);
34 converter.loadModel();
35
36 // Parse.
37 const IR::Node *v1 = V1::V1ParserDriver::parse(stream, sourceFile, sourceLine);
38 if (::P4::errorCount() > 0 || v1 == nullptr) return nullptr;
39
40 // Convert to P4-16.
41 if (Log::verbose()) std::cerr << "Converting to P4-16" << std::endl;
42 v1 = v1->apply(converter);
43 if (::P4::errorCount() > 0 || v1 == nullptr) return nullptr;
44 BUG_CHECK(v1->is<IR::P4Program>(), "Conversion returned %1%", v1);
45 return v1->to<IR::P4Program>();
46}
47#endif
56#ifdef SUPPORT_P4_14
57template <typename C = P4V1::Converter>
58#else
59inline
60#endif
61const IR::P4Program *parseP4File(const ParserOptions &options) {
62 BUG_CHECK(&options == &P4CContext::get().options(),
63 "Parsing using options that don't match the current "
64 "compiler context");
65
66 const IR::P4Program *result = nullptr;
67 if (options.doNotPreprocess) {
68 auto *file = fopen(options.file.c_str(), "r");
69 if (file == nullptr) {
70 ::P4::error(ErrorType::ERR_NOT_FOUND, "%1%: No such file or directory.", options.file);
71 return nullptr;
72 }
73#ifdef SUPPORT_P4_14
74 result = options.isv1() ? parseV1Program<FILE *, C>(file, options.file.string(), 1,
75 options.getDebugHook())
76 : P4ParserDriver::parse(file, options.file.string());
77#else
78 result = P4ParserDriver::parse(file, options.file.string());
79#endif
80 fclose(file);
81 } else {
82 auto preprocessorResult = options.preprocess();
83 if (!preprocessorResult.has_value()) {
84 return nullptr;
85 }
86// Need to assign file here because the parser requires an lvalue.
87#ifdef SUPPORT_P4_14
88 result =
89 options.isv1()
90 ? parseV1Program<FILE *, C>(preprocessorResult.value().get(), options.file.string(),
91 1, options.getDebugHook())
92 : P4ParserDriver::parse(preprocessorResult.value().get(), options.file.string());
93#else
94 result = P4ParserDriver::parse(preprocessorResult.value().get(), options.file.string());
95#endif
96 }
97
98 if (::P4::errorCount() > 0) {
99 ::P4::error(ErrorType::ERR_OVERLIMIT, "%1% errors encountered, aborting compilation",
101 return nullptr;
102 }
103 BUG_CHECK(result != nullptr, "Parsing failed, but we didn't report an error");
104 return result;
105}
106
118#ifdef SUPPORT_P4_14
119const IR::P4Program *parseP4String(
120 const char *sourceFile, unsigned sourceLine, const std::string &input,
121 CompilerOptions::FrontendVersion version = CompilerOptions::FrontendVersion::P4_16);
122const IR::P4Program *parseP4String(
123 const std::string &input,
124 CompilerOptions::FrontendVersion version = CompilerOptions::FrontendVersion::P4_16);
125#else
126[[deprecated(
127 "P4-14 support is disabled, this function will always parse P4-16. Use the overload without "
128 "the version argument.")]]
129const IR::P4Program *parseP4String(const char *sourceFile, unsigned sourceLine,
130 const std::string &input,
131 CompilerOptions::FrontendVersion version);
132[[deprecated(
133 "P4-14 support is disabled, this function will always parse P4-16. Use the overload without "
134 "the version argument.")]]
135const IR::P4Program *parseP4String(const std::string &input,
136 CompilerOptions::FrontendVersion version);
137const IR::P4Program *parseP4String(const char *sourceFile, unsigned sourceLine,
138 const std::string &input);
139const IR::P4Program *parseP4String(const std::string &input);
140#endif
141
142} // namespace P4
143
144#endif /* FRONTENDS_COMMON_PARSEINPUT_H_ */
Definition node.h:44
static P4CContext & get()
Definition parser_options.cpp:540
static const IR::P4Program * parse(std::istream &in, std::string_view sourceFile, unsigned sourceLine=1)
Definition parserDriver.cpp:136
Definition parser_options.h:42
Definition constantParsing.h:13
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:13
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition lib/error.h:49
const IR::P4Program * parseP4File(const ParserOptions &options)
Definition parseInput.h:61
unsigned errorCount()
Definition lib/error.h:25