From a84d93cde00febb44be7918f6a44dc658d83d155 Mon Sep 17 00:00:00 2001 From: Robert Iannucci Date: Thu, 27 Sep 2012 16:37:37 -0700 Subject: block parse method done --- src/graph.h | 1 + src/lexer.cc | 389 ++++++++++++++++++++++++++----------------------- src/lexer.h | 1 + src/lexer.in.cc | 2 + src/manifest_parser.cc | 68 ++++++++- src/manifest_parser.h | 1 + 6 files changed, 277 insertions(+), 185 deletions(-) diff --git a/src/graph.h b/src/graph.h index 9e924f7..4d24c72 100644 --- a/src/graph.h +++ b/src/graph.h @@ -131,6 +131,7 @@ struct Rule { EvalString command_; EvalString description_; EvalString depfile_; + EvalString pool_; EvalString rspfile_; EvalString rspfile_content_; }; diff --git a/src/lexer.cc b/src/lexer.cc index 5d7d185..685fe81 100644 --- a/src/lexer.cc +++ b/src/lexer.cc @@ -83,6 +83,7 @@ const char* Lexer::TokenName(Token t) { case NEWLINE: return "newline"; case PIPE2: return "'||'"; case PIPE: return "'|'"; + case POOL: return "'pool'"; case RULE: return "'rule'"; case SUBNINJA: return "'subninja'"; case TEOF: return "eof"; @@ -162,63 +163,71 @@ Lexer::Token Lexer::ReadToken() { }; yych = *p; - if (yych <= 'Z') { + if (yych <= '^') { if (yych <= ',') { if (yych <= 0x1F) { - if (yych <= 0x00) goto yy21; + if (yych <= 0x00) goto yy22; if (yych == '\n') goto yy6; - goto yy23; + goto yy24; } else { if (yych <= ' ') goto yy2; if (yych == '#') goto yy4; - goto yy23; + goto yy24; } } else { if (yych <= ':') { - if (yych == '/') goto yy23; - if (yych <= '9') goto yy20; - goto yy14; + if (yych == '/') goto yy24; + if (yych <= '9') goto yy21; + goto yy15; } else { - if (yych == '=') goto yy12; - if (yych <= '@') goto yy23; - goto yy20; + if (yych <= '=') { + if (yych <= '<') goto yy24; + goto yy13; + } else { + if (yych <= '@') goto yy24; + if (yych <= 'Z') goto yy21; + goto yy24; + } } } } else { - if (yych <= 'h') { - if (yych <= 'a') { - if (yych == '_') goto yy20; - if (yych <= '`') goto yy23; - goto yy20; + if (yych <= 'i') { + if (yych <= 'b') { + if (yych == '`') goto yy24; + if (yych <= 'a') goto yy21; + goto yy8; } else { - if (yych <= 'b') goto yy8; - if (yych == 'd') goto yy11; - goto yy20; + if (yych == 'd') goto yy12; + if (yych <= 'h') goto yy21; + goto yy19; } } else { - if (yych <= 's') { - if (yych <= 'i') goto yy18; - if (yych <= 'q') goto yy20; - if (yych <= 'r') goto yy10; - goto yy19; + if (yych <= 'r') { + if (yych == 'p') goto yy10; + if (yych <= 'q') goto yy21; + goto yy11; } else { - if (yych <= 'z') goto yy20; - if (yych == '|') goto yy16; - goto yy23; + if (yych <= 'z') { + if (yych <= 's') goto yy20; + goto yy21; + } else { + if (yych == '|') goto yy17; + goto yy24; + } } } } yy2: yyaccept = 0; yych = *(q = ++p); - goto yy65; + goto yy70; yy3: { token = INDENT; break; } yy4: yyaccept = 1; yych = *(q = ++p); if (yych <= 0x00) goto yy5; - if (yych != '\r') goto yy60; + if (yych != '\r') goto yy65; yy5: { token = ERROR; break; } yy6: @@ -227,159 +236,173 @@ yy7: { token = NEWLINE; break; } yy8: ++p; - if ((yych = *p) == 'u') goto yy54; - goto yy25; + if ((yych = *p) == 'u') goto yy59; + goto yy26; yy9: { token = IDENT; break; } yy10: yych = *++p; - if (yych == 'u') goto yy50; - goto yy25; + if (yych == 'o') goto yy55; + goto yy26; yy11: yych = *++p; - if (yych == 'e') goto yy43; - goto yy25; + if (yych == 'u') goto yy51; + goto yy26; yy12: + yych = *++p; + if (yych == 'e') goto yy44; + goto yy26; +yy13: ++p; { token = EQUALS; break; } -yy14: +yy15: ++p; { token = COLON; break; } -yy16: +yy17: ++p; - if ((yych = *p) == '|') goto yy41; + if ((yych = *p) == '|') goto yy42; { token = PIPE; break; } -yy18: - yych = *++p; - if (yych == 'n') goto yy34; - goto yy25; yy19: yych = *++p; - if (yych == 'u') goto yy26; - goto yy25; + if (yych == 'n') goto yy35; + goto yy26; yy20: yych = *++p; - goto yy25; + if (yych == 'u') goto yy27; + goto yy26; yy21: + yych = *++p; + goto yy26; +yy22: ++p; { token = TEOF; break; } -yy23: +yy24: yych = *++p; goto yy5; -yy24: +yy25: ++p; yych = *p; -yy25: +yy26: if (yybm[0+yych] & 32) { - goto yy24; + goto yy25; } goto yy9; -yy26: +yy27: yych = *++p; - if (yych != 'b') goto yy25; + if (yych != 'b') goto yy26; yych = *++p; - if (yych != 'n') goto yy25; + if (yych != 'n') goto yy26; yych = *++p; - if (yych != 'i') goto yy25; + if (yych != 'i') goto yy26; yych = *++p; - if (yych != 'n') goto yy25; + if (yych != 'n') goto yy26; yych = *++p; - if (yych != 'j') goto yy25; + if (yych != 'j') goto yy26; yych = *++p; - if (yych != 'a') goto yy25; + if (yych != 'a') goto yy26; ++p; if (yybm[0+(yych = *p)] & 32) { - goto yy24; + goto yy25; } { token = SUBNINJA; break; } -yy34: +yy35: yych = *++p; - if (yych != 'c') goto yy25; + if (yych != 'c') goto yy26; yych = *++p; - if (yych != 'l') goto yy25; + if (yych != 'l') goto yy26; yych = *++p; - if (yych != 'u') goto yy25; + if (yych != 'u') goto yy26; yych = *++p; - if (yych != 'd') goto yy25; + if (yych != 'd') goto yy26; yych = *++p; - if (yych != 'e') goto yy25; + if (yych != 'e') goto yy26; ++p; if (yybm[0+(yych = *p)] & 32) { - goto yy24; + goto yy25; } { token = INCLUDE; break; } -yy41: +yy42: ++p; { token = PIPE2; break; } -yy43: +yy44: yych = *++p; - if (yych != 'f') goto yy25; + if (yych != 'f') goto yy26; yych = *++p; - if (yych != 'a') goto yy25; + if (yych != 'a') goto yy26; yych = *++p; - if (yych != 'u') goto yy25; + if (yych != 'u') goto yy26; yych = *++p; - if (yych != 'l') goto yy25; + if (yych != 'l') goto yy26; yych = *++p; - if (yych != 't') goto yy25; + if (yych != 't') goto yy26; ++p; if (yybm[0+(yych = *p)] & 32) { - goto yy24; + goto yy25; } { token = DEFAULT; break; } -yy50: +yy51: yych = *++p; - if (yych != 'l') goto yy25; + if (yych != 'l') goto yy26; yych = *++p; - if (yych != 'e') goto yy25; + if (yych != 'e') goto yy26; ++p; if (yybm[0+(yych = *p)] & 32) { - goto yy24; + goto yy25; } { token = RULE; break; } -yy54: +yy55: yych = *++p; - if (yych != 'i') goto yy25; + if (yych != 'o') goto yy26; yych = *++p; - if (yych != 'l') goto yy25; + if (yych != 'l') goto yy26; + ++p; + if (yybm[0+(yych = *p)] & 32) { + goto yy25; + } + { token = POOL; break; } +yy59: + yych = *++p; + if (yych != 'i') goto yy26; yych = *++p; - if (yych != 'd') goto yy25; + if (yych != 'l') goto yy26; + yych = *++p; + if (yych != 'd') goto yy26; ++p; if (yybm[0+(yych = *p)] & 32) { - goto yy24; + goto yy25; } { token = BUILD; break; } -yy59: +yy64: ++p; yych = *p; -yy60: +yy65: if (yybm[0+yych] & 64) { - goto yy59; + goto yy64; } - if (yych <= 0x00) goto yy61; - if (yych <= '\f') goto yy62; -yy61: + if (yych <= 0x00) goto yy66; + if (yych <= '\f') goto yy67; +yy66: p = q; if (yyaccept <= 0) { goto yy3; } else { goto yy5; } -yy62: +yy67: ++p; { continue; } -yy64: +yy69: yyaccept = 0; q = ++p; yych = *p; -yy65: +yy70: if (yybm[0+yych] & 128) { - goto yy64; + goto yy69; } - if (yych == '\n') goto yy66; - if (yych == '#') goto yy59; + if (yych == '\n') goto yy71; + if (yych == '#') goto yy64; goto yy3; -yy66: +yy71: ++p; yych = *p; goto yy7; @@ -445,39 +468,39 @@ void Lexer::EatWhitespace() { }; yych = *p; if (yych <= ' ') { - if (yych <= 0x00) goto yy73; - if (yych <= 0x1F) goto yy75; + if (yych <= 0x00) goto yy78; + if (yych <= 0x1F) goto yy80; } else { - if (yych == '$') goto yy71; - goto yy75; + if (yych == '$') goto yy76; + goto yy80; } ++p; yych = *p; - goto yy79; -yy70: + goto yy84; +yy75: { continue; } -yy71: +yy76: ++p; - if ((yych = *p) == '\n') goto yy76; -yy72: + if ((yych = *p) == '\n') goto yy81; +yy77: { break; } -yy73: +yy78: ++p; { break; } -yy75: +yy80: yych = *++p; - goto yy72; -yy76: + goto yy77; +yy81: ++p; { continue; } -yy78: +yy83: ++p; yych = *p; -yy79: +yy84: if (yybm[0+yych] & 128) { - goto yy78; + goto yy83; } - goto yy70; + goto yy75; } } @@ -527,40 +550,40 @@ bool Lexer::ReadIdent(string* out) { yych = *p; if (yych <= '@') { if (yych <= '.') { - if (yych <= ',') goto yy84; + if (yych <= ',') goto yy89; } else { - if (yych <= '/') goto yy84; - if (yych >= ':') goto yy84; + if (yych <= '/') goto yy89; + if (yych >= ':') goto yy89; } } else { if (yych <= '_') { - if (yych <= 'Z') goto yy82; - if (yych <= '^') goto yy84; + if (yych <= 'Z') goto yy87; + if (yych <= '^') goto yy89; } else { - if (yych <= '`') goto yy84; - if (yych >= '{') goto yy84; + if (yych <= '`') goto yy89; + if (yych >= '{') goto yy89; } } -yy82: +yy87: ++p; yych = *p; - goto yy87; -yy83: + goto yy92; +yy88: { out->assign(start, p - start); break; } -yy84: +yy89: ++p; { return false; } -yy86: +yy91: ++p; yych = *p; -yy87: +yy92: if (yybm[0+yych] & 128) { - goto yy86; + goto yy91; } - goto yy83; + goto yy88; } } @@ -615,29 +638,29 @@ bool Lexer::ReadEvalString(EvalString* eval, bool path, string* err) { yych = *p; if (yych <= ' ') { if (yych <= '\n') { - if (yych <= 0x00) goto yy96; - if (yych >= '\n') goto yy92; + if (yych <= 0x00) goto yy101; + if (yych >= '\n') goto yy97; } else { - if (yych == '\r') goto yy98; - if (yych >= ' ') goto yy92; + if (yych == '\r') goto yy103; + if (yych >= ' ') goto yy97; } } else { if (yych <= '9') { - if (yych == '$') goto yy94; + if (yych == '$') goto yy99; } else { - if (yych <= ':') goto yy92; - if (yych == '|') goto yy92; + if (yych <= ':') goto yy97; + if (yych == '|') goto yy97; } } ++p; yych = *p; - goto yy121; -yy91: + goto yy126; +yy96: { eval->AddText(StringPiece(start, p - start)); continue; } -yy92: +yy97: ++p; { if (path) { @@ -650,137 +673,137 @@ yy92: continue; } } -yy94: +yy99: ++p; if ((yych = *p) <= '/') { if (yych <= ' ') { - if (yych == '\n') goto yy110; - if (yych <= 0x1F) goto yy99; - goto yy101; + if (yych == '\n') goto yy115; + if (yych <= 0x1F) goto yy104; + goto yy106; } else { if (yych <= '$') { - if (yych <= '#') goto yy99; - goto yy103; + if (yych <= '#') goto yy104; + goto yy108; } else { - if (yych == '-') goto yy105; - goto yy99; + if (yych == '-') goto yy110; + goto yy104; } } } else { if (yych <= '^') { if (yych <= ':') { - if (yych <= '9') goto yy105; - goto yy107; + if (yych <= '9') goto yy110; + goto yy112; } else { - if (yych <= '@') goto yy99; - if (yych <= 'Z') goto yy105; - goto yy99; + if (yych <= '@') goto yy104; + if (yych <= 'Z') goto yy110; + goto yy104; } } else { if (yych <= '`') { - if (yych <= '_') goto yy105; - goto yy99; + if (yych <= '_') goto yy110; + goto yy104; } else { - if (yych <= 'z') goto yy105; - if (yych <= '{') goto yy109; - goto yy99; + if (yych <= 'z') goto yy110; + if (yych <= '{') goto yy114; + goto yy104; } } } -yy95: +yy100: { last_token_ = start; return Error(DescribeLastError(), err); } -yy96: +yy101: ++p; { last_token_ = start; return Error("unexpected EOF", err); } -yy98: +yy103: yych = *++p; - goto yy95; -yy99: + goto yy100; +yy104: ++p; -yy100: +yy105: { last_token_ = start; return Error("bad $-escape (literal $ must be written as $$)", err); } -yy101: +yy106: ++p; { eval->AddText(StringPiece(" ", 1)); continue; } -yy103: +yy108: ++p; { eval->AddText(StringPiece("$", 1)); continue; } -yy105: +yy110: ++p; yych = *p; - goto yy119; -yy106: + goto yy124; +yy111: { eval->AddSpecial(StringPiece(start + 1, p - start - 1)); continue; } -yy107: +yy112: ++p; { eval->AddText(StringPiece(":", 1)); continue; } -yy109: +yy114: yych = *(q = ++p); if (yybm[0+yych] & 32) { - goto yy113; + goto yy118; } - goto yy100; -yy110: + goto yy105; +yy115: ++p; yych = *p; if (yybm[0+yych] & 16) { - goto yy110; + goto yy115; } { continue; } -yy113: +yy118: ++p; yych = *p; if (yybm[0+yych] & 32) { - goto yy113; + goto yy118; } - if (yych == '}') goto yy116; + if (yych == '}') goto yy121; p = q; - goto yy100; -yy116: + goto yy105; +yy121: ++p; { eval->AddSpecial(StringPiece(start + 2, p - start - 3)); continue; } -yy118: +yy123: ++p; yych = *p; -yy119: +yy124: if (yybm[0+yych] & 64) { - goto yy118; + goto yy123; } - goto yy106; -yy120: + goto yy111; +yy125: ++p; yych = *p; -yy121: +yy126: if (yybm[0+yych] & 128) { - goto yy120; + goto yy125; } - goto yy91; + goto yy96; } } diff --git a/src/lexer.h b/src/lexer.h index 03c59f2..f366556 100644 --- a/src/lexer.h +++ b/src/lexer.h @@ -41,6 +41,7 @@ struct Lexer { NEWLINE, PIPE, PIPE2, + POOL, RULE, SUBNINJA, TEOF, diff --git a/src/lexer.in.cc b/src/lexer.in.cc index 7ae9c61..93d5540 100644 --- a/src/lexer.in.cc +++ b/src/lexer.in.cc @@ -82,6 +82,7 @@ const char* Lexer::TokenName(Token t) { case NEWLINE: return "newline"; case PIPE2: return "'||'"; case PIPE: return "'|'"; + case POOL: return "'pool'"; case RULE: return "'rule'"; case SUBNINJA: return "'subninja'"; case TEOF: return "eof"; @@ -135,6 +136,7 @@ Lexer::Token Lexer::ReadToken() { [ ]*[\n] { token = NEWLINE; break; } [ ]+ { token = INDENT; break; } "build" { token = BUILD; break; } + "pool" { token = POOL; break; } "rule" { token = RULE; break; } "default" { token = DEFAULT; break; } "=" { token = EQUALS; break; } diff --git a/src/manifest_parser.cc b/src/manifest_parser.cc index d2c7f1c..9ab973f 100644 --- a/src/manifest_parser.cc +++ b/src/manifest_parser.cc @@ -47,6 +47,10 @@ bool ManifestParser::Parse(const string& filename, const string& input, for (;;) { Lexer::Token token = lexer_.ReadToken(); switch (token) { + case Lexer::POOL: + if (!ParsePool(err)) + return false; + break; case Lexer::BUILD: if (!ParseEdge(err)) return false; @@ -91,6 +95,46 @@ bool ManifestParser::Parse(const string& filename, const string& input, return false; // not reached } + +bool ManifestParser::ParsePool(string* err) { + string name; + if (!lexer_.ReadIdent(&name)) + return lexer_.Error("expected pool name", err); + + if (!ExpectToken(Lexer::NEWLINE, err)) + return false; + + if (state_->LookupPool(name) != NULL) + return lexer_.Error("duplicate pool '" + name + "'", err); + + Pool* pool = new Pool(name); + bool set_depth = false; + + while (lexer_.PeekToken(Lexer::INDENT)) { + string key; + EvalString value; + if (!ParseLet(&key, &value, err)) + return false; + + if (key == "depth") { + string depth_string = value.Evaluate(env_); + pool->depth_ = atol(depth_string.c_str()); + if (pool->depth() <= 0) + return lexer_.Error("invalid pool depth", err); + set_depth = true; + } else { + return lexer_.Error("unexpected variable '" + key + "'", err); + } + } + + if (!set_depth) + return lexer_.Error("expected 'depth =' line", err); + + state_->AddPool(pool); + return true; +} + + bool ManifestParser::ParseRule(string* err) { string name; if (!lexer_.ReadIdent(&name)) @@ -126,6 +170,8 @@ bool ManifestParser::ParseRule(string* err) { rule->rspfile_ = value; } else if (key == "rspfile_content") { rule->rspfile_content_ = value; + } else if (key == "pool") { + rule->pool_ = value; } else { // Die on other keyvals for now; revisit if we want to add a // scope here. @@ -252,6 +298,7 @@ bool ManifestParser::ParseEdge(string* err) { // Default to using outer env. BindingEnv* env = env_; + Pool* pool = NULL; // But create and fill a nested env if there are variables in scope. if (lexer_.PeekToken(Lexer::INDENT)) { @@ -262,11 +309,28 @@ bool ManifestParser::ParseEdge(string* err) { EvalString val; if (!ParseLet(&key, &val, err)) return false; - env->AddBinding(key, val.Evaluate(env_)); + if (key == "pool") { + string pool_name = val.Evaluate(env_); + pool = state_->LookupPool(pool_name); + if (pool == NULL) + return lexer_.Error("undefined pool '" + pool_name + "'", err); + } else { + env->AddBinding(key, val.Evaluate(env_)); + } } while (lexer_.PeekToken(Lexer::INDENT)); } - Edge* edge = state_->AddEdge(rule, &State::kDefaultPool); + if (pool == NULL) { + if (!rule->pool_.empty()) { + pool = state_->LookupPool(rule->pool_.Evaluate(env_)); + if (pool == NULL) + return lexer_.Error("cannot resolve pool for this edge.", err); + } else { + pool = &State::kDefaultPool; + } + } + + Edge* edge = state_->AddEdge(rule, pool); edge->env_ = env; for (vector::iterator i = ins.begin(); i != ins.end(); ++i) { string path = i->Evaluate(env); diff --git a/src/manifest_parser.h b/src/manifest_parser.h index a2c6c93..a08e5af 100644 --- a/src/manifest_parser.h +++ b/src/manifest_parser.h @@ -50,6 +50,7 @@ private: bool Parse(const string& filename, const string& input, string* err); /// Parse various statement types. + bool ParsePool(string* err); bool ParseRule(string* err); bool ParseLet(string* key, EvalString* val, string* err); bool ParseEdge(string* err); -- cgit v0.12