mirror of
https://github.com/reactos/ninja.git
synced 2024-11-27 05:30:25 +00:00
Factor out a base class of ManifestParser
Create a Parser base class that holds parser functionality not specific to the build manifest file format. This will allow it to be re-used for other parsers later.
This commit is contained in:
parent
215a190a57
commit
d718808392
@ -504,6 +504,7 @@ for name in ['build',
|
|||||||
'line_printer',
|
'line_printer',
|
||||||
'manifest_parser',
|
'manifest_parser',
|
||||||
'metrics',
|
'metrics',
|
||||||
|
'parser',
|
||||||
'state',
|
'state',
|
||||||
'string_piece_util',
|
'string_piece_util',
|
||||||
'util',
|
'util',
|
||||||
|
@ -18,41 +18,18 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "disk_interface.h"
|
|
||||||
#include "graph.h"
|
#include "graph.h"
|
||||||
#include "metrics.h"
|
|
||||||
#include "state.h"
|
#include "state.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
ManifestParser::ManifestParser(State* state, FileReader* file_reader,
|
ManifestParser::ManifestParser(State* state, FileReader* file_reader,
|
||||||
ManifestParserOptions options)
|
ManifestParserOptions options)
|
||||||
: state_(state), file_reader_(file_reader),
|
: Parser(state, file_reader),
|
||||||
options_(options), quiet_(false) {
|
options_(options), quiet_(false) {
|
||||||
env_ = &state->bindings_;
|
env_ = &state->bindings_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ManifestParser::Load(const string& filename, string* err, Lexer* parent) {
|
|
||||||
METRIC_RECORD(".ninja parse");
|
|
||||||
string contents;
|
|
||||||
string read_err;
|
|
||||||
if (file_reader_->ReadFile(filename, &contents, &read_err) != FileReader::Okay) {
|
|
||||||
*err = "loading '" + filename + "': " + read_err;
|
|
||||||
if (parent)
|
|
||||||
parent->Error(string(*err), err);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The lexer needs a nul byte at the end of its input, to know when it's done.
|
|
||||||
// It takes a StringPiece, and StringPiece's string constructor uses
|
|
||||||
// string::data(). data()'s return value isn't guaranteed to be
|
|
||||||
// null-terminated (although in practice - libc++, libstdc++, msvc's stl --
|
|
||||||
// it is, and C++11 demands that too), so add an explicit nul byte.
|
|
||||||
contents.resize(contents.size() + 1);
|
|
||||||
|
|
||||||
return Parse(filename, contents, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ManifestParser::Parse(const string& filename, const string& input,
|
bool ManifestParser::Parse(const string& filename, const string& input,
|
||||||
string* err) {
|
string* err) {
|
||||||
lexer_.Start(filename, input);
|
lexer_.Start(filename, input);
|
||||||
@ -434,14 +411,3 @@ bool ManifestParser::ParseFileInclude(bool new_scope, string* err) {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ManifestParser::ExpectToken(Lexer::Token expected, string* err) {
|
|
||||||
Lexer::Token token = lexer_.ReadToken();
|
|
||||||
if (token != expected) {
|
|
||||||
string message = string("expected ") + Lexer::TokenName(expected);
|
|
||||||
message += string(", got ") + Lexer::TokenName(token);
|
|
||||||
message += Lexer::TokenErrorHint(expected);
|
|
||||||
return lexer_.Error(message, err);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
@ -15,16 +15,10 @@
|
|||||||
#ifndef NINJA_MANIFEST_PARSER_H_
|
#ifndef NINJA_MANIFEST_PARSER_H_
|
||||||
#define NINJA_MANIFEST_PARSER_H_
|
#define NINJA_MANIFEST_PARSER_H_
|
||||||
|
|
||||||
#include <string>
|
#include "parser.h"
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
#include "lexer.h"
|
|
||||||
|
|
||||||
struct BindingEnv;
|
struct BindingEnv;
|
||||||
struct EvalString;
|
struct EvalString;
|
||||||
struct FileReader;
|
|
||||||
struct State;
|
|
||||||
|
|
||||||
enum DupeEdgeAction {
|
enum DupeEdgeAction {
|
||||||
kDupeEdgeActionWarn,
|
kDupeEdgeActionWarn,
|
||||||
@ -45,13 +39,10 @@ struct ManifestParserOptions {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Parses .ninja files.
|
/// Parses .ninja files.
|
||||||
struct ManifestParser {
|
struct ManifestParser : public Parser {
|
||||||
ManifestParser(State* state, FileReader* file_reader,
|
ManifestParser(State* state, FileReader* file_reader,
|
||||||
ManifestParserOptions options = ManifestParserOptions());
|
ManifestParserOptions options = ManifestParserOptions());
|
||||||
|
|
||||||
/// Load and parse a file.
|
|
||||||
bool Load(const string& filename, string* err, Lexer* parent = NULL);
|
|
||||||
|
|
||||||
/// Parse a text string of input. Used by tests.
|
/// Parse a text string of input. Used by tests.
|
||||||
bool ParseTest(const string& input, string* err) {
|
bool ParseTest(const string& input, string* err) {
|
||||||
quiet_ = true;
|
quiet_ = true;
|
||||||
@ -72,14 +63,7 @@ private:
|
|||||||
/// Parse either a 'subninja' or 'include' line.
|
/// Parse either a 'subninja' or 'include' line.
|
||||||
bool ParseFileInclude(bool new_scope, string* err);
|
bool ParseFileInclude(bool new_scope, string* err);
|
||||||
|
|
||||||
/// If the next token is not \a expected, produce an error string
|
|
||||||
/// saying "expected foo, got bar".
|
|
||||||
bool ExpectToken(Lexer::Token expected, string* err);
|
|
||||||
|
|
||||||
State* state_;
|
|
||||||
BindingEnv* env_;
|
BindingEnv* env_;
|
||||||
FileReader* file_reader_;
|
|
||||||
Lexer lexer_;
|
|
||||||
ManifestParserOptions options_;
|
ManifestParserOptions options_;
|
||||||
bool quiet_;
|
bool quiet_;
|
||||||
};
|
};
|
||||||
|
51
src/parser.cc
Normal file
51
src/parser.cc
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
#include "parser.h"
|
||||||
|
|
||||||
|
#include "disk_interface.h"
|
||||||
|
#include "metrics.h"
|
||||||
|
|
||||||
|
bool Parser::Load(const string& filename, string* err, Lexer* parent) {
|
||||||
|
METRIC_RECORD(".ninja parse");
|
||||||
|
string contents;
|
||||||
|
string read_err;
|
||||||
|
if (file_reader_->ReadFile(filename, &contents, &read_err) !=
|
||||||
|
FileReader::Okay) {
|
||||||
|
*err = "loading '" + filename + "': " + read_err;
|
||||||
|
if (parent)
|
||||||
|
parent->Error(string(*err), err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The lexer needs a nul byte at the end of its input, to know when it's done.
|
||||||
|
// It takes a StringPiece, and StringPiece's string constructor uses
|
||||||
|
// string::data(). data()'s return value isn't guaranteed to be
|
||||||
|
// null-terminated (although in practice - libc++, libstdc++, msvc's stl --
|
||||||
|
// it is, and C++11 demands that too), so add an explicit nul byte.
|
||||||
|
contents.resize(contents.size() + 1);
|
||||||
|
|
||||||
|
return Parse(filename, contents, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Parser::ExpectToken(Lexer::Token expected, string* err) {
|
||||||
|
Lexer::Token token = lexer_.ReadToken();
|
||||||
|
if (token != expected) {
|
||||||
|
string message = string("expected ") + Lexer::TokenName(expected);
|
||||||
|
message += string(", got ") + Lexer::TokenName(token);
|
||||||
|
message += Lexer::TokenErrorHint(expected);
|
||||||
|
return lexer_.Error(message, err);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
50
src/parser.h
Normal file
50
src/parser.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// 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_PARSER_H_
|
||||||
|
#define NINJA_PARSER_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#include "lexer.h"
|
||||||
|
|
||||||
|
struct FileReader;
|
||||||
|
struct State;
|
||||||
|
|
||||||
|
/// Base class for parsers.
|
||||||
|
struct Parser {
|
||||||
|
Parser(State* state, FileReader* file_reader)
|
||||||
|
: state_(state), file_reader_(file_reader) {}
|
||||||
|
|
||||||
|
/// Load and parse a file.
|
||||||
|
bool Load(const string& filename, string* err, Lexer* parent = NULL);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// If the next token is not \a expected, produce an error string
|
||||||
|
/// saying "expected foo, got bar".
|
||||||
|
bool ExpectToken(Lexer::Token expected, string* err);
|
||||||
|
|
||||||
|
State* state_;
|
||||||
|
FileReader* file_reader_;
|
||||||
|
Lexer lexer_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Parse a file, given its contents as a string.
|
||||||
|
virtual bool Parse(const string& filename, const string& input,
|
||||||
|
string* err) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NINJA_PARSER_H_
|
Loading…
Reference in New Issue
Block a user