block parse method done
authorRobert Iannucci <robbie@rail.com>
Thu, 27 Sep 2012 23:37:37 +0000 (16:37 -0700)
committerRobert Iannucci <robbie@rail.com>
Sat, 10 Nov 2012 05:55:01 +0000 (21:55 -0800)
src/graph.h
src/lexer.cc
src/lexer.h
src/lexer.in.cc
src/manifest_parser.cc
src/manifest_parser.h

index 9e924f7..4d24c72 100644 (file)
@@ -131,6 +131,7 @@ struct Rule {
   EvalString command_;
   EvalString description_;
   EvalString depfile_;
+  EvalString pool_;
   EvalString rspfile_;
   EvalString rspfile_content_;
 };
index 5d7d185..685fe81 100644 (file)
@@ -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;
 }
 
   }
index 03c59f2..f366556 100644 (file)
@@ -41,6 +41,7 @@ struct Lexer {
     NEWLINE,
     PIPE,
     PIPE2,
+    POOL,
     RULE,
     SUBNINJA,
     TEOF,
index 7ae9c61..93d5540 100644 (file)
@@ -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; }
index d2c7f1c..9ab973f 100644 (file)
@@ -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<EvalString>::iterator i = ins.begin(); i != ins.end(); ++i) {
     string path = i->Evaluate(env);
index a2c6c93..a08e5af 100644 (file)
@@ -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);