summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure.py1
-rw-r--r--src/manifest_parser.cc36
-rw-r--r--src/manifest_parser.h20
-rw-r--r--src/parser.cc51
-rw-r--r--src/parser.h50
5 files changed, 105 insertions, 53 deletions
diff --git a/configure.py b/configure.py
index 20b389d..6aece3f 100755
--- a/configure.py
+++ b/configure.py
@@ -504,6 +504,7 @@ for name in ['build',
'line_printer',
'manifest_parser',
'metrics',
+ 'parser',
'state',
'string_piece_util',
'util',
diff --git a/src/manifest_parser.cc b/src/manifest_parser.cc
index 27c423b..226acb0 100644
--- a/src/manifest_parser.cc
+++ b/src/manifest_parser.cc
@@ -18,41 +18,18 @@
#include <stdlib.h>
#include <vector>
-#include "disk_interface.h"
#include "graph.h"
-#include "metrics.h"
#include "state.h"
#include "util.h"
#include "version.h"
ManifestParser::ManifestParser(State* state, FileReader* file_reader,
ManifestParserOptions options)
- : state_(state), file_reader_(file_reader),
+ : Parser(state, file_reader),
options_(options), quiet_(false) {
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,
string* err) {
lexer_.Start(filename, input);
@@ -434,14 +411,3 @@ bool ManifestParser::ParseFileInclude(bool new_scope, string* err) {
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;
-}
diff --git a/src/manifest_parser.h b/src/manifest_parser.h
index 76c17b0..e14d069 100644
--- a/src/manifest_parser.h
+++ b/src/manifest_parser.h
@@ -15,16 +15,10 @@
#ifndef NINJA_MANIFEST_PARSER_H_
#define NINJA_MANIFEST_PARSER_H_
-#include <string>
-
-using namespace std;
-
-#include "lexer.h"
+#include "parser.h"
struct BindingEnv;
struct EvalString;
-struct FileReader;
-struct State;
enum DupeEdgeAction {
kDupeEdgeActionWarn,
@@ -45,13 +39,10 @@ struct ManifestParserOptions {
};
/// Parses .ninja files.
-struct ManifestParser {
+struct ManifestParser : public Parser {
ManifestParser(State* state, FileReader* file_reader,
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.
bool ParseTest(const string& input, string* err) {
quiet_ = true;
@@ -72,14 +63,7 @@ private:
/// Parse either a 'subninja' or 'include' line.
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_;
- FileReader* file_reader_;
- Lexer lexer_;
ManifestParserOptions options_;
bool quiet_;
};
diff --git a/src/parser.cc b/src/parser.cc
new file mode 100644
index 0000000..745c532
--- /dev/null
+++ b/src/parser.cc
@@ -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;
+}
diff --git a/src/parser.h b/src/parser.h
new file mode 100644
index 0000000..e2d2b97
--- /dev/null
+++ b/src/parser.h
@@ -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_