aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShinichiro Hamaji <shinichiro.hamaji@gmail.com>2015-06-16 23:07:21 +0900
committerShinichiro Hamaji <shinichiro.hamaji@gmail.com>2015-06-18 11:25:43 +0900
commit42b625f3573f8026e8c6da3231fdf1721320da25 (patch)
tree94d0580d2590ffc1222d72f0703e2cd30b468dfc
parent5e26e2277f026594eebc303225c937245b73c7f5 (diff)
downloadandroid_build_kati-42b625f3573f8026e8c6da3231fdf1721320da25.tar.gz
android_build_kati-42b625f3573f8026e8c6da3231fdf1721320da25.tar.bz2
android_build_kati-42b625f3573f8026e8c6da3231fdf1721320da25.zip
[C++] Parse include directives
-rw-r--r--ast.cc13
-rw-r--r--ast.h44
-rw-r--r--eval.cc12
-rw-r--r--eval.h6
-rw-r--r--main.cc3
-rw-r--r--parser.cc66
-rw-r--r--parser.h3
7 files changed, 146 insertions, 1 deletions
diff --git a/ast.cc b/ast.cc
index b755ce9..79cea85 100644
--- a/ast.cc
+++ b/ast.cc
@@ -41,6 +41,11 @@ string CommandAST::DebugString() const {
expr->DebugString().c_str(), LOCF(loc()));
}
+string IncludeAST::DebugString() const {
+ return StringPrintf("IncludeAST(%s, loc=%s:%d)",
+ expr->DebugString().c_str(), LOCF(loc()));
+}
+
RuleAST::~RuleAST() {
delete expr;
delete after_term;
@@ -66,3 +71,11 @@ CommandAST::~CommandAST() {
void CommandAST::Eval(Evaluator* ev) const {
ev->EvalCommand(this);
}
+
+IncludeAST::~IncludeAST() {
+ delete expr;
+}
+
+void IncludeAST::Eval(Evaluator* ev) const {
+ ev->EvalInclude(this);
+}
diff --git a/ast.h b/ast.h
index 8c0ceea..99c8ae5 100644
--- a/ast.h
+++ b/ast.h
@@ -2,6 +2,7 @@
#define AST_H_
#include <string>
+#include <vector>
#include "loc.h"
#include "string_piece.h"
@@ -24,6 +25,13 @@ enum struct AssignDirective {
EXPORT,
};
+enum struct CondOp {
+ IFEQ,
+ IFNEQ,
+ IFDEF,
+ IFNDEF,
+};
+
struct AST {
public:
virtual ~AST();
@@ -79,4 +87,40 @@ struct CommandAST : public AST {
virtual string DebugString() const;
};
+struct IfAST : public AST {
+ CondOp op;
+ Value* lhs;
+ Value* rhs;
+ vector<AST*> true_stmts;
+ vector<AST*> false_stmts;
+
+ virtual ~IfAST();
+
+ virtual void Eval(Evaluator* ev) const;
+
+ virtual string DebugString() const;
+};
+
+struct IncludeAST : public AST {
+ Value* expr;
+ char op; // '-' or 0.
+
+ virtual ~IncludeAST();
+
+ virtual void Eval(Evaluator* ev) const;
+
+ virtual string DebugString() const;
+};
+
+struct ExportAST : public AST {
+ Value* expr;
+ bool is_export;
+
+ virtual ~ExportAST();
+
+ virtual void Eval(Evaluator* ev) const;
+
+ virtual string DebugString() const;
+};
+
#endif // AST_H_
diff --git a/eval.cc b/eval.cc
index b8d2fe6..56c9623 100644
--- a/eval.cc
+++ b/eval.cc
@@ -105,6 +105,18 @@ void Evaluator::EvalCommand(const CommandAST* ast) {
LOG("Command: %s", ast->expr->DebugString().c_str());
}
+void Evaluator::EvalIf(const IfAST* ast) {
+ ERROR("TODO");
+}
+
+void Evaluator::EvalInclude(const IncludeAST* ast) {
+ ERROR("TODO");
+}
+
+void Evaluator::EvalExport(const ExportAST* ast) {
+ ERROR("TODO");
+}
+
Var* Evaluator::LookupVar(StringPiece name) {
// TODO: TSV.
Var* v = vars_->Lookup(name);
diff --git a/eval.h b/eval.h
index 51460a9..3c84c3f 100644
--- a/eval.h
+++ b/eval.h
@@ -11,6 +11,9 @@ using namespace std;
class AssignAST;
class CommandAST;
+class ExportAST;
+class IfAST;
+class IncludeAST;
class Makefile;
class Rule;
class RuleAST;
@@ -34,6 +37,9 @@ class Evaluator {
void EvalAssign(const AssignAST* ast);
void EvalRule(const RuleAST* ast);
void EvalCommand(const CommandAST* ast);
+ void EvalIf(const IfAST* ast);
+ void EvalInclude(const IncludeAST* ast);
+ void EvalExport(const ExportAST* ast);
Var* LookupVar(StringPiece name);
// For target specific variables.
diff --git a/main.cc b/main.cc
index cdb06ee..a504154 100644
--- a/main.cc
+++ b/main.cc
@@ -10,6 +10,7 @@
#include "fileutil.h"
#include "func.h"
#include "log.h"
+#include "parser.h"
#include "string_piece.h"
#include "strutil.h"
#include "var.h"
@@ -34,6 +35,7 @@ static void Init() {
InitSymtab();
InitFuncTable();
InitDepNodePool();
+ InitParser();
if (g_makefile == NULL) {
if (Exists("GNUmakefile")) {
@@ -49,6 +51,7 @@ static void Init() {
}
static void Quit() {
+ QuitParser();
QuitDepNodePool();
QuitFuncTable();
QuitSymtab();
diff --git a/parser.cc b/parser.cc
index 8d872de..9ddd8cc 100644
--- a/parser.cc
+++ b/parser.cc
@@ -1,5 +1,7 @@
#include "parser.h"
+#include <unordered_map>
+
#include "ast.h"
#include "file.h"
#include "loc.h"
@@ -43,6 +45,24 @@ class Parser {
}
}
+ static void Init() {
+ make_directives_ = new unordered_map<StringPiece, DirectiveHandler>;
+ (*make_directives_)["include"] = &Parser::ParseIncludeAST;
+ (*make_directives_)["-include"] = &Parser::ParseIncludeAST;
+
+ shortest_directive_len_ = 9999;
+ longest_directive_len_ = 0;
+ for (auto p : *make_directives_) {
+ size_t len = p.first.size();
+ shortest_directive_len_ = min(len, shortest_directive_len_);
+ longest_directive_len_ = max(len, longest_directive_len_);
+ }
+ }
+
+ static void Quit() {
+ delete make_directives_;
+ }
+
private:
void Error(const string& msg) {
ERROR("%s:%d: %s", LOCF(loc_), msg.c_str());
@@ -78,7 +98,10 @@ class Parser {
return;
}
- // TODO: directive.
+ line = line.StripLeftSpaces();
+ if (HandleDirective(line)) {
+ return;
+ }
size_t sep = line.find_first_of(STRING_PIECE("=:"));
if (sep == string::npos) {
@@ -145,6 +168,29 @@ class Parser {
state_ = ParserState::NOT_AFTER_RULE;
}
+ void ParseIncludeAST(StringPiece line, StringPiece directive) {
+ IncludeAST* ast = new IncludeAST();
+ ast->expr = ParseExpr(line, false);
+ ast->op = directive[0] == '-' ? '-' : 0;
+ out_asts_->push_back(ast);
+ }
+
+ bool HandleDirective(StringPiece line) {
+ if (line.size() < shortest_directive_len_)
+ return false;
+ StringPiece prefix = line.substr(0, longest_directive_len_ + 1);
+ size_t space_index = prefix.find(' ');
+ if (space_index == string::npos)
+ return false;
+ StringPiece directive = prefix.substr(0, space_index);
+ auto found = make_directives_->find(directive);
+ if (found == make_directives_->end())
+ return false;
+
+ (this->*found->second)(line.substr(directive.size() + 1), directive);
+ return true;
+ }
+
StringPiece buf_;
size_t l_;
ParserState state_;
@@ -153,6 +199,12 @@ class Parser {
Loc loc_;
bool fixed_lineno_;
+
+ typedef void (Parser::*DirectiveHandler)(
+ StringPiece line, StringPiece directive);
+ static unordered_map<StringPiece, DirectiveHandler>* make_directives_;
+ static size_t shortest_directive_len_;
+ static size_t longest_directive_len_;
};
void Parse(Makefile* mk) {
@@ -161,3 +213,15 @@ void Parse(Makefile* mk) {
mk->mutable_asts());
parser.Parse();
}
+
+void InitParser() {
+ Parser::Init();
+}
+
+void QuitParser() {
+ Parser::Quit();
+}
+
+unordered_map<StringPiece, Parser::DirectiveHandler>* Parser::make_directives_;
+size_t Parser::shortest_directive_len_;
+size_t Parser::longest_directive_len_;
diff --git a/parser.h b/parser.h
index b82741b..92be36c 100644
--- a/parser.h
+++ b/parser.h
@@ -5,4 +5,7 @@ class Makefile;
void Parse(Makefile* mk);
+void InitParser();
+void QuitParser();
+
#endif // PARSER_H_