blob: 665a805bfc1c9417d5a643a97ed9fe12a6df6b69 [file] [log] [blame]
// Copyright 2018 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef NINJA_MANIFEST_CHUNK_PARSER_H_
#define NINJA_MANIFEST_CHUNK_PARSER_H_
#include <stdlib.h>
#include <string>
#include <vector>
#include "disk_interface.h"
#include "eval_env.h"
#include "graph.h"
#include "state.h"
#include "string_piece.h"
struct Lexer;
namespace manifest_chunk {
struct Error {
std::string msg_;
};
struct RequiredVersion {
StringPiece version_;
};
struct Include {
LexedPath path_;
bool new_scope_ = false;
size_t diag_pos_ = 0;
};
struct DefaultTarget {
RelativePosition pos_;
LexedPath parsed_path_;
size_t diag_pos_ = 0;
};
/// A group of manifest declarations generated while parsing a chunk.
struct Clump {
Clump(const LoadedFile& file) : file_(file) {}
const LoadedFile& file_;
BasePosition pos_;
std::vector<Binding*> bindings_;
std::vector<Rule*> rules_;
std::vector<Pool*> pools_;
std::vector<Edge*> edges_;
std::vector<DefaultTarget*> default_targets_;
/// A count of non-implicit outputs across all edges.
size_t edge_output_count_ = 0;
DeclIndex decl_count() const { return next_index_; }
/// Allocate an index within the clump. Once the parallelized chunk parsing is
/// finished, each clump's base position will be computed, giving every clump
/// item both a DFS "depth-first-search" position and a position within the
/// tree of scopes.
RelativePosition AllocNextPos() { return { &pos_, next_index_++ }; }
private:
DeclIndex next_index_ = 0;
};
/// This class could be replaced with std::variant from C++17.
struct ParserItem {
enum Kind {
kError, kRequiredVersion, kInclude, kClump
};
Kind kind;
union {
Error* error;
RequiredVersion* required_version;
Include* include;
Clump* clump;
} u;
ParserItem(Error* val) : kind(kError) { u.error = val; }
ParserItem(RequiredVersion* val) : kind(kRequiredVersion) { u.required_version = val; }
ParserItem(Include* val) : kind(kInclude) { u.include = val; }
ParserItem(Clump* val) : kind(kClump) { u.clump = val; }
};
/// Parse a chunk of a manifest. If the parser encounters a syntactic error, the
/// final item will be an error object.
void ParseChunk(const LoadedFile& file, StringPiece chunk_content,
std::vector<ParserItem>* out);
/// Split the input into chunks of declarations.
std::vector<StringPiece> SplitManifestIntoChunks(StringPiece input);
} // namespace manifest_chunk
#endif // NINJA_MANIFEST_CHUNK_PARSER_H_