Remove accidental changes
[platform/upstream/ninja.git] / src / lexer.cc
1 /* Generated by re2c 0.13.5 */
2 // Copyright 2011 Google Inc. All Rights Reserved.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15
16 #include "lexer.h"
17
18 #include <stdio.h>
19
20 #include "eval_env.h"
21 #include "util.h"
22
23 bool Lexer::Error(const string& message, string* err) {
24   // Compute line/column.
25   int line = 1;
26   const char* context = input_.str_;
27   for (const char* p = input_.str_; p < last_token_; ++p) {
28     if (*p == '\n') {
29       ++line;
30       context = p + 1;
31     }
32   }
33   int col = last_token_ ? (int)(last_token_ - context) : 0;
34
35   char buf[1024];
36   snprintf(buf, sizeof(buf), "%s:%d: ", filename_.AsString().c_str(), line);
37   *err = buf;
38   *err += message + "\n";
39
40   // Add some context to the message.
41   const int kTruncateColumn = 72;
42   if (col > 0 && col < kTruncateColumn) {
43     int len;
44     bool truncated = true;
45     for (len = 0; len < kTruncateColumn; ++len) {
46       if (context[len] == 0 || context[len] == '\n') {
47         truncated = false;
48         break;
49       }
50     }
51     *err += string(context, len);
52     if (truncated)
53       *err += "...";
54     *err += "\n";
55     *err += string(col, ' ');
56     *err += "^ near here";
57   }
58
59   return false;
60 }
61
62 Lexer::Lexer(const char* input) {
63   Start("input", input);
64 }
65
66 void Lexer::Start(StringPiece filename, StringPiece input) {
67   filename_ = filename;
68   input_ = input;
69   ofs_ = input_.str_;
70   last_token_ = NULL;
71 }
72
73 const char* Lexer::TokenName(Token t) {
74   switch (t) {
75   case ERROR:    return "lexing error";
76   case BUILD:    return "'build'";
77   case COLON:    return "':'";
78   case DEFAULT:  return "'default'";
79   case EQUALS:   return "'='";
80   case IDENT:    return "identifier";
81   case INCLUDE:  return "'include'";
82   case INDENT:   return "indent";
83   case NEWLINE:  return "newline";
84   case PIPE2:    return "'||'";
85   case PIPE:     return "'|'";
86   case POOL:     return "'pool'";
87   case RULE:     return "'rule'";
88   case SUBNINJA: return "'subninja'";
89   case TEOF:     return "eof";
90   }
91   return NULL;  // not reached
92 }
93
94 const char* Lexer::TokenErrorHint(Token expected) {
95   switch (expected) {
96   case COLON:
97     return " ($ also escapes ':')";
98   default:
99     return "";
100   }
101 }
102
103 string Lexer::DescribeLastError() {
104   if (last_token_) {
105     switch (last_token_[0]) {
106     case '\t':
107       return "tabs are not allowed, use spaces";
108     }
109   }
110   return "lexing error";
111 }
112
113 void Lexer::UnreadToken() {
114   ofs_ = last_token_;
115 }
116
117 Lexer::Token Lexer::ReadToken() {
118   const char* p = ofs_;
119   const char* q;
120   const char* start;
121   Lexer::Token token;
122   for (;;) {
123     start = p;
124     
125 {
126         unsigned char yych;
127         unsigned int yyaccept = 0;
128         static const unsigned char yybm[] = {
129                   0,  64,  64,  64,  64,  64,  64,  64, 
130                  64,  64,   0,  64,  64,  64,  64,  64, 
131                  64,  64,  64,  64,  64,  64,  64,  64, 
132                  64,  64,  64,  64,  64,  64,  64,  64, 
133                 192,  64,  64,  64,  64,  64,  64,  64, 
134                  64,  64,  64,  64,  64,  96,  96,  64, 
135                  96,  96,  96,  96,  96,  96,  96,  96, 
136                  96,  96,  64,  64,  64,  64,  64,  64, 
137                  64,  96,  96,  96,  96,  96,  96,  96, 
138                  96,  96,  96,  96,  96,  96,  96,  96, 
139                  96,  96,  96,  96,  96,  96,  96,  96, 
140                  96,  96,  96,  64,  64,  64,  64,  96, 
141                  64,  96,  96,  96,  96,  96,  96,  96, 
142                  96,  96,  96,  96,  96,  96,  96,  96, 
143                  96,  96,  96,  96,  96,  96,  96,  96, 
144                  96,  96,  96,  64,  64,  64,  64,  64, 
145                  64,  64,  64,  64,  64,  64,  64,  64, 
146                  64,  64,  64,  64,  64,  64,  64,  64, 
147                  64,  64,  64,  64,  64,  64,  64,  64, 
148                  64,  64,  64,  64,  64,  64,  64,  64, 
149                  64,  64,  64,  64,  64,  64,  64,  64, 
150                  64,  64,  64,  64,  64,  64,  64,  64, 
151                  64,  64,  64,  64,  64,  64,  64,  64, 
152                  64,  64,  64,  64,  64,  64,  64,  64, 
153                  64,  64,  64,  64,  64,  64,  64,  64, 
154                  64,  64,  64,  64,  64,  64,  64,  64, 
155                  64,  64,  64,  64,  64,  64,  64,  64, 
156                  64,  64,  64,  64,  64,  64,  64,  64, 
157                  64,  64,  64,  64,  64,  64,  64,  64, 
158                  64,  64,  64,  64,  64,  64,  64,  64, 
159                  64,  64,  64,  64,  64,  64,  64,  64, 
160                  64,  64,  64,  64,  64,  64,  64,  64, 
161         };
162
163         yych = *p;
164         if (yych <= 'Z') {
165                 if (yych <= '#') {
166                         if (yych <= '\f') {
167                                 if (yych <= 0x00) goto yy23;
168                                 if (yych == '\n') goto yy7;
169                                 goto yy25;
170                         } else {
171                                 if (yych <= 0x1F) {
172                                         if (yych <= '\r') goto yy6;
173                                         goto yy25;
174                                 } else {
175                                         if (yych <= ' ') goto yy2;
176                                         if (yych <= '"') goto yy25;
177                                         goto yy4;
178                                 }
179                         }
180                 } else {
181                         if (yych <= '9') {
182                                 if (yych <= ',') goto yy25;
183                                 if (yych == '/') goto yy25;
184                                 goto yy22;
185                         } else {
186                                 if (yych <= '<') {
187                                         if (yych <= ':') goto yy16;
188                                         goto yy25;
189                                 } else {
190                                         if (yych <= '=') goto yy14;
191                                         if (yych <= '@') goto yy25;
192                                         goto yy22;
193                                 }
194                         }
195                 }
196         } else {
197                 if (yych <= 'i') {
198                         if (yych <= 'a') {
199                                 if (yych == '_') goto yy22;
200                                 if (yych <= '`') goto yy25;
201                                 goto yy22;
202                         } else {
203                                 if (yych <= 'c') {
204                                         if (yych <= 'b') goto yy9;
205                                         goto yy22;
206                                 } else {
207                                         if (yych <= 'd') goto yy13;
208                                         if (yych <= 'h') goto yy22;
209                                         goto yy20;
210                                 }
211                         }
212                 } else {
213                         if (yych <= 'r') {
214                                 if (yych == 'p') goto yy11;
215                                 if (yych <= 'q') goto yy22;
216                                 goto yy12;
217                         } else {
218                                 if (yych <= 'z') {
219                                         if (yych <= 's') goto yy21;
220                                         goto yy22;
221                                 } else {
222                                         if (yych == '|') goto yy18;
223                                         goto yy25;
224                                 }
225                         }
226                 }
227         }
228 yy2:
229         yyaccept = 0;
230         yych = *(q = ++p);
231         goto yy73;
232 yy3:
233         { token = INDENT;   break; }
234 yy4:
235         yyaccept = 1;
236         yych = *(q = ++p);
237         if (yych >= 0x01) goto yy68;
238 yy5:
239         { token = ERROR;    break; }
240 yy6:
241         yych = *++p;
242         if (yych == '\n') goto yy65;
243         goto yy5;
244 yy7:
245         ++p;
246 yy8:
247         { token = NEWLINE;  break; }
248 yy9:
249         ++p;
250         if ((yych = *p) == 'u') goto yy60;
251         goto yy27;
252 yy10:
253         { token = IDENT;    break; }
254 yy11:
255         yych = *++p;
256         if (yych == 'o') goto yy56;
257         goto yy27;
258 yy12:
259         yych = *++p;
260         if (yych == 'u') goto yy52;
261         goto yy27;
262 yy13:
263         yych = *++p;
264         if (yych == 'e') goto yy45;
265         goto yy27;
266 yy14:
267         ++p;
268         { token = EQUALS;   break; }
269 yy16:
270         ++p;
271         { token = COLON;    break; }
272 yy18:
273         ++p;
274         if ((yych = *p) == '|') goto yy43;
275         { token = PIPE;     break; }
276 yy20:
277         yych = *++p;
278         if (yych == 'n') goto yy36;
279         goto yy27;
280 yy21:
281         yych = *++p;
282         if (yych == 'u') goto yy28;
283         goto yy27;
284 yy22:
285         yych = *++p;
286         goto yy27;
287 yy23:
288         ++p;
289         { token = TEOF;     break; }
290 yy25:
291         yych = *++p;
292         goto yy5;
293 yy26:
294         ++p;
295         yych = *p;
296 yy27:
297         if (yybm[0+yych] & 32) {
298                 goto yy26;
299         }
300         goto yy10;
301 yy28:
302         yych = *++p;
303         if (yych != 'b') goto yy27;
304         yych = *++p;
305         if (yych != 'n') goto yy27;
306         yych = *++p;
307         if (yych != 'i') goto yy27;
308         yych = *++p;
309         if (yych != 'n') goto yy27;
310         yych = *++p;
311         if (yych != 'j') goto yy27;
312         yych = *++p;
313         if (yych != 'a') goto yy27;
314         ++p;
315         if (yybm[0+(yych = *p)] & 32) {
316                 goto yy26;
317         }
318         { token = SUBNINJA; break; }
319 yy36:
320         yych = *++p;
321         if (yych != 'c') goto yy27;
322         yych = *++p;
323         if (yych != 'l') goto yy27;
324         yych = *++p;
325         if (yych != 'u') goto yy27;
326         yych = *++p;
327         if (yych != 'd') goto yy27;
328         yych = *++p;
329         if (yych != 'e') goto yy27;
330         ++p;
331         if (yybm[0+(yych = *p)] & 32) {
332                 goto yy26;
333         }
334         { token = INCLUDE;  break; }
335 yy43:
336         ++p;
337         { token = PIPE2;    break; }
338 yy45:
339         yych = *++p;
340         if (yych != 'f') goto yy27;
341         yych = *++p;
342         if (yych != 'a') goto yy27;
343         yych = *++p;
344         if (yych != 'u') goto yy27;
345         yych = *++p;
346         if (yych != 'l') goto yy27;
347         yych = *++p;
348         if (yych != 't') goto yy27;
349         ++p;
350         if (yybm[0+(yych = *p)] & 32) {
351                 goto yy26;
352         }
353         { token = DEFAULT;  break; }
354 yy52:
355         yych = *++p;
356         if (yych != 'l') goto yy27;
357         yych = *++p;
358         if (yych != 'e') goto yy27;
359         ++p;
360         if (yybm[0+(yych = *p)] & 32) {
361                 goto yy26;
362         }
363         { token = RULE;     break; }
364 yy56:
365         yych = *++p;
366         if (yych != 'o') goto yy27;
367         yych = *++p;
368         if (yych != 'l') goto yy27;
369         ++p;
370         if (yybm[0+(yych = *p)] & 32) {
371                 goto yy26;
372         }
373         { token = POOL;     break; }
374 yy60:
375         yych = *++p;
376         if (yych != 'i') goto yy27;
377         yych = *++p;
378         if (yych != 'l') goto yy27;
379         yych = *++p;
380         if (yych != 'd') goto yy27;
381         ++p;
382         if (yybm[0+(yych = *p)] & 32) {
383                 goto yy26;
384         }
385         { token = BUILD;    break; }
386 yy65:
387         ++p;
388         { token = NEWLINE;  break; }
389 yy67:
390         ++p;
391         yych = *p;
392 yy68:
393         if (yybm[0+yych] & 64) {
394                 goto yy67;
395         }
396         if (yych >= 0x01) goto yy70;
397 yy69:
398         p = q;
399         if (yyaccept <= 0) {
400                 goto yy3;
401         } else {
402                 goto yy5;
403         }
404 yy70:
405         ++p;
406         { continue; }
407 yy72:
408         yyaccept = 0;
409         q = ++p;
410         yych = *p;
411 yy73:
412         if (yybm[0+yych] & 128) {
413                 goto yy72;
414         }
415         if (yych <= '\f') {
416                 if (yych != '\n') goto yy3;
417         } else {
418                 if (yych <= '\r') goto yy75;
419                 if (yych == '#') goto yy67;
420                 goto yy3;
421         }
422         yych = *++p;
423         goto yy8;
424 yy75:
425         ++p;
426         if ((yych = *p) == '\n') goto yy65;
427         goto yy69;
428 }
429
430   }
431
432   last_token_ = start;
433   ofs_ = p;
434   if (token != NEWLINE && token != TEOF)
435     EatWhitespace();
436   return token;
437 }
438
439 bool Lexer::PeekToken(Token token) {
440   Token t = ReadToken();
441   if (t == token)
442     return true;
443   UnreadToken();
444   return false;
445 }
446
447 void Lexer::EatWhitespace() {
448   const char* p = ofs_;
449   const char* q;
450   for (;;) {
451     ofs_ = p;
452     
453 {
454         unsigned char yych;
455         static const unsigned char yybm[] = {
456                   0,   0,   0,   0,   0,   0,   0,   0, 
457                   0,   0,   0,   0,   0,   0,   0,   0, 
458                   0,   0,   0,   0,   0,   0,   0,   0, 
459                   0,   0,   0,   0,   0,   0,   0,   0, 
460                 128,   0,   0,   0,   0,   0,   0,   0, 
461                   0,   0,   0,   0,   0,   0,   0,   0, 
462                   0,   0,   0,   0,   0,   0,   0,   0, 
463                   0,   0,   0,   0,   0,   0,   0,   0, 
464                   0,   0,   0,   0,   0,   0,   0,   0, 
465                   0,   0,   0,   0,   0,   0,   0,   0, 
466                   0,   0,   0,   0,   0,   0,   0,   0, 
467                   0,   0,   0,   0,   0,   0,   0,   0, 
468                   0,   0,   0,   0,   0,   0,   0,   0, 
469                   0,   0,   0,   0,   0,   0,   0,   0, 
470                   0,   0,   0,   0,   0,   0,   0,   0, 
471                   0,   0,   0,   0,   0,   0,   0,   0, 
472                   0,   0,   0,   0,   0,   0,   0,   0, 
473                   0,   0,   0,   0,   0,   0,   0,   0, 
474                   0,   0,   0,   0,   0,   0,   0,   0, 
475                   0,   0,   0,   0,   0,   0,   0,   0, 
476                   0,   0,   0,   0,   0,   0,   0,   0, 
477                   0,   0,   0,   0,   0,   0,   0,   0, 
478                   0,   0,   0,   0,   0,   0,   0,   0, 
479                   0,   0,   0,   0,   0,   0,   0,   0, 
480                   0,   0,   0,   0,   0,   0,   0,   0, 
481                   0,   0,   0,   0,   0,   0,   0,   0, 
482                   0,   0,   0,   0,   0,   0,   0,   0, 
483                   0,   0,   0,   0,   0,   0,   0,   0, 
484                   0,   0,   0,   0,   0,   0,   0,   0, 
485                   0,   0,   0,   0,   0,   0,   0,   0, 
486                   0,   0,   0,   0,   0,   0,   0,   0, 
487                   0,   0,   0,   0,   0,   0,   0,   0, 
488         };
489         yych = *p;
490         if (yych <= ' ') {
491                 if (yych <= 0x00) goto yy82;
492                 if (yych <= 0x1F) goto yy84;
493         } else {
494                 if (yych == '$') goto yy80;
495                 goto yy84;
496         }
497         ++p;
498         yych = *p;
499         goto yy92;
500 yy79:
501         { continue; }
502 yy80:
503         yych = *(q = ++p);
504         if (yych == '\n') goto yy85;
505         if (yych == '\r') goto yy87;
506 yy81:
507         { break; }
508 yy82:
509         ++p;
510         { break; }
511 yy84:
512         yych = *++p;
513         goto yy81;
514 yy85:
515         ++p;
516         { continue; }
517 yy87:
518         yych = *++p;
519         if (yych == '\n') goto yy89;
520         p = q;
521         goto yy81;
522 yy89:
523         ++p;
524         { continue; }
525 yy91:
526         ++p;
527         yych = *p;
528 yy92:
529         if (yybm[0+yych] & 128) {
530                 goto yy91;
531         }
532         goto yy79;
533 }
534
535   }
536 }
537
538 bool Lexer::ReadIdent(string* out) {
539   const char* p = ofs_;
540   for (;;) {
541     const char* start = p;
542     
543 {
544         unsigned char yych;
545         static const unsigned char yybm[] = {
546                   0,   0,   0,   0,   0,   0,   0,   0, 
547                   0,   0,   0,   0,   0,   0,   0,   0, 
548                   0,   0,   0,   0,   0,   0,   0,   0, 
549                   0,   0,   0,   0,   0,   0,   0,   0, 
550                   0,   0,   0,   0,   0,   0,   0,   0, 
551                   0,   0,   0,   0,   0, 128, 128,   0, 
552                 128, 128, 128, 128, 128, 128, 128, 128, 
553                 128, 128,   0,   0,   0,   0,   0,   0, 
554                   0, 128, 128, 128, 128, 128, 128, 128, 
555                 128, 128, 128, 128, 128, 128, 128, 128, 
556                 128, 128, 128, 128, 128, 128, 128, 128, 
557                 128, 128, 128,   0,   0,   0,   0, 128, 
558                   0, 128, 128, 128, 128, 128, 128, 128, 
559                 128, 128, 128, 128, 128, 128, 128, 128, 
560                 128, 128, 128, 128, 128, 128, 128, 128, 
561                 128, 128, 128,   0,   0,   0,   0,   0, 
562                   0,   0,   0,   0,   0,   0,   0,   0, 
563                   0,   0,   0,   0,   0,   0,   0,   0, 
564                   0,   0,   0,   0,   0,   0,   0,   0, 
565                   0,   0,   0,   0,   0,   0,   0,   0, 
566                   0,   0,   0,   0,   0,   0,   0,   0, 
567                   0,   0,   0,   0,   0,   0,   0,   0, 
568                   0,   0,   0,   0,   0,   0,   0,   0, 
569                   0,   0,   0,   0,   0,   0,   0,   0, 
570                   0,   0,   0,   0,   0,   0,   0,   0, 
571                   0,   0,   0,   0,   0,   0,   0,   0, 
572                   0,   0,   0,   0,   0,   0,   0,   0, 
573                   0,   0,   0,   0,   0,   0,   0,   0, 
574                   0,   0,   0,   0,   0,   0,   0,   0, 
575                   0,   0,   0,   0,   0,   0,   0,   0, 
576                   0,   0,   0,   0,   0,   0,   0,   0, 
577                   0,   0,   0,   0,   0,   0,   0,   0, 
578         };
579         yych = *p;
580         if (yych <= '@') {
581                 if (yych <= '.') {
582                         if (yych <= ',') goto yy97;
583                 } else {
584                         if (yych <= '/') goto yy97;
585                         if (yych >= ':') goto yy97;
586                 }
587         } else {
588                 if (yych <= '_') {
589                         if (yych <= 'Z') goto yy95;
590                         if (yych <= '^') goto yy97;
591                 } else {
592                         if (yych <= '`') goto yy97;
593                         if (yych >= '{') goto yy97;
594                 }
595         }
596 yy95:
597         ++p;
598         yych = *p;
599         goto yy100;
600 yy96:
601         {
602       out->assign(start, p - start);
603       break;
604     }
605 yy97:
606         ++p;
607         { return false; }
608 yy99:
609         ++p;
610         yych = *p;
611 yy100:
612         if (yybm[0+yych] & 128) {
613                 goto yy99;
614         }
615         goto yy96;
616 }
617
618   }
619   ofs_ = p;
620   EatWhitespace();
621   return true;
622 }
623
624 bool Lexer::ReadEvalString(EvalString* eval, bool path, string* err) {
625   const char* p = ofs_;
626   const char* q;
627   const char* start;
628   for (;;) {
629     start = p;
630     
631 {
632         unsigned char yych;
633         static const unsigned char yybm[] = {
634                   0, 128, 128, 128, 128, 128, 128, 128, 
635                 128, 128,   0, 128, 128,   0, 128, 128, 
636                 128, 128, 128, 128, 128, 128, 128, 128, 
637                 128, 128, 128, 128, 128, 128, 128, 128, 
638                  16, 128, 128, 128,   0, 128, 128, 128, 
639                 128, 128, 128, 128, 128, 224, 160, 128, 
640                 224, 224, 224, 224, 224, 224, 224, 224, 
641                 224, 224,   0, 128, 128, 128, 128, 128, 
642                 128, 224, 224, 224, 224, 224, 224, 224, 
643                 224, 224, 224, 224, 224, 224, 224, 224, 
644                 224, 224, 224, 224, 224, 224, 224, 224, 
645                 224, 224, 224, 128, 128, 128, 128, 224, 
646                 128, 224, 224, 224, 224, 224, 224, 224, 
647                 224, 224, 224, 224, 224, 224, 224, 224, 
648                 224, 224, 224, 224, 224, 224, 224, 224, 
649                 224, 224, 224, 128,   0, 128, 128, 128, 
650                 128, 128, 128, 128, 128, 128, 128, 128, 
651                 128, 128, 128, 128, 128, 128, 128, 128, 
652                 128, 128, 128, 128, 128, 128, 128, 128, 
653                 128, 128, 128, 128, 128, 128, 128, 128, 
654                 128, 128, 128, 128, 128, 128, 128, 128, 
655                 128, 128, 128, 128, 128, 128, 128, 128, 
656                 128, 128, 128, 128, 128, 128, 128, 128, 
657                 128, 128, 128, 128, 128, 128, 128, 128, 
658                 128, 128, 128, 128, 128, 128, 128, 128, 
659                 128, 128, 128, 128, 128, 128, 128, 128, 
660                 128, 128, 128, 128, 128, 128, 128, 128, 
661                 128, 128, 128, 128, 128, 128, 128, 128, 
662                 128, 128, 128, 128, 128, 128, 128, 128, 
663                 128, 128, 128, 128, 128, 128, 128, 128, 
664                 128, 128, 128, 128, 128, 128, 128, 128, 
665                 128, 128, 128, 128, 128, 128, 128, 128, 
666         };
667         yych = *p;
668         if (yych <= ' ') {
669                 if (yych <= '\n') {
670                         if (yych <= 0x00) goto yy110;
671                         if (yych >= '\n') goto yy107;
672                 } else {
673                         if (yych == '\r') goto yy105;
674                         if (yych >= ' ') goto yy107;
675                 }
676         } else {
677                 if (yych <= '9') {
678                         if (yych == '$') goto yy109;
679                 } else {
680                         if (yych <= ':') goto yy107;
681                         if (yych == '|') goto yy107;
682                 }
683         }
684         ++p;
685         yych = *p;
686         goto yy140;
687 yy104:
688         {
689       eval->AddText(StringPiece(start, p - start));
690       continue;
691     }
692 yy105:
693         ++p;
694         if ((yych = *p) == '\n') goto yy137;
695         {
696       last_token_ = start;
697       return Error(DescribeLastError(), err);
698     }
699 yy107:
700         ++p;
701         {
702       if (path) {
703         p = start;
704         break;
705       } else {
706         if (*start == '\n')
707           break;
708         eval->AddText(StringPiece(start, 1));
709         continue;
710       }
711     }
712 yy109:
713         yych = *++p;
714         if (yych <= '-') {
715                 if (yych <= 0x1F) {
716                         if (yych <= '\n') {
717                                 if (yych <= '\t') goto yy112;
718                                 goto yy124;
719                         } else {
720                                 if (yych == '\r') goto yy114;
721                                 goto yy112;
722                         }
723                 } else {
724                         if (yych <= '#') {
725                                 if (yych <= ' ') goto yy115;
726                                 goto yy112;
727                         } else {
728                                 if (yych <= '$') goto yy117;
729                                 if (yych <= ',') goto yy112;
730                                 goto yy119;
731                         }
732                 }
733         } else {
734                 if (yych <= 'Z') {
735                         if (yych <= '9') {
736                                 if (yych <= '/') goto yy112;
737                                 goto yy119;
738                         } else {
739                                 if (yych <= ':') goto yy121;
740                                 if (yych <= '@') goto yy112;
741                                 goto yy119;
742                         }
743                 } else {
744                         if (yych <= '`') {
745                                 if (yych == '_') goto yy119;
746                                 goto yy112;
747                         } else {
748                                 if (yych <= 'z') goto yy119;
749                                 if (yych <= '{') goto yy123;
750                                 goto yy112;
751                         }
752                 }
753         }
754 yy110:
755         ++p;
756         {
757       last_token_ = start;
758       return Error("unexpected EOF", err);
759     }
760 yy112:
761         ++p;
762 yy113:
763         {
764       last_token_ = start;
765       return Error("bad $-escape (literal $ must be written as $$)", err);
766     }
767 yy114:
768         yych = *++p;
769         if (yych == '\n') goto yy134;
770         goto yy113;
771 yy115:
772         ++p;
773         {
774       eval->AddText(StringPiece(" ", 1));
775       continue;
776     }
777 yy117:
778         ++p;
779         {
780       eval->AddText(StringPiece("$", 1));
781       continue;
782     }
783 yy119:
784         ++p;
785         yych = *p;
786         goto yy133;
787 yy120:
788         {
789       eval->AddSpecial(StringPiece(start + 1, p - start - 1));
790       continue;
791     }
792 yy121:
793         ++p;
794         {
795       eval->AddText(StringPiece(":", 1));
796       continue;
797     }
798 yy123:
799         yych = *(q = ++p);
800         if (yybm[0+yych] & 32) {
801                 goto yy127;
802         }
803         goto yy113;
804 yy124:
805         ++p;
806         yych = *p;
807         if (yybm[0+yych] & 16) {
808                 goto yy124;
809         }
810         {
811       continue;
812     }
813 yy127:
814         ++p;
815         yych = *p;
816         if (yybm[0+yych] & 32) {
817                 goto yy127;
818         }
819         if (yych == '}') goto yy130;
820         p = q;
821         goto yy113;
822 yy130:
823         ++p;
824         {
825       eval->AddSpecial(StringPiece(start + 2, p - start - 3));
826       continue;
827     }
828 yy132:
829         ++p;
830         yych = *p;
831 yy133:
832         if (yybm[0+yych] & 64) {
833                 goto yy132;
834         }
835         goto yy120;
836 yy134:
837         ++p;
838         yych = *p;
839         if (yych == ' ') goto yy134;
840         {
841       continue;
842     }
843 yy137:
844         ++p;
845         {
846       if (path)
847         p = start;
848       break;
849     }
850 yy139:
851         ++p;
852         yych = *p;
853 yy140:
854         if (yybm[0+yych] & 128) {
855                 goto yy139;
856         }
857         goto yy104;
858 }
859
860   }
861   last_token_ = start;
862   ofs_ = p;
863   if (path)
864     EatWhitespace();
865   // Non-path strings end in newlines, so there's no whitespace to eat.
866   return true;
867 }