Merge changes Iaa05196d,I8bd4f4de,I721e1ff9 into tizen
[platform/upstream/ninja.git] / src / lexer.cc
1 /* Generated by re2c 0.16 */
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* line_start = input_.str_;
27   for (const char* p = input_.str_; p < last_token_; ++p) {
28     if (*p == '\n') {
29       ++line;
30       line_start = p + 1;
31     }
32   }
33   int col = last_token_ ? (int)(last_token_ - line_start) : 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 (line_start[len] == 0 || line_start[len] == '\n') {
47         truncated = false;
48         break;
49       }
50     }
51     *err += string(line_start, 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, 128, 128, 128, 128, 128, 128, 128, 
130                 128, 128,   0, 128, 128, 128, 128, 128, 
131                 128, 128, 128, 128, 128, 128, 128, 128, 
132                 128, 128, 128, 128, 128, 128, 128, 128, 
133                 160, 128, 128, 128, 128, 128, 128, 128, 
134                 128, 128, 128, 128, 128, 192, 192, 128, 
135                 192, 192, 192, 192, 192, 192, 192, 192, 
136                 192, 192, 128, 128, 128, 128, 128, 128, 
137                 128, 192, 192, 192, 192, 192, 192, 192, 
138                 192, 192, 192, 192, 192, 192, 192, 192, 
139                 192, 192, 192, 192, 192, 192, 192, 192, 
140                 192, 192, 192, 128, 128, 128, 128, 192, 
141                 128, 192, 192, 192, 192, 192, 192, 192, 
142                 192, 192, 192, 192, 192, 192, 192, 192, 
143                 192, 192, 192, 192, 192, 192, 192, 192, 
144                 192, 192, 192, 128, 128, 128, 128, 128, 
145                 128, 128, 128, 128, 128, 128, 128, 128, 
146                 128, 128, 128, 128, 128, 128, 128, 128, 
147                 128, 128, 128, 128, 128, 128, 128, 128, 
148                 128, 128, 128, 128, 128, 128, 128, 128, 
149                 128, 128, 128, 128, 128, 128, 128, 128, 
150                 128, 128, 128, 128, 128, 128, 128, 128, 
151                 128, 128, 128, 128, 128, 128, 128, 128, 
152                 128, 128, 128, 128, 128, 128, 128, 128, 
153                 128, 128, 128, 128, 128, 128, 128, 128, 
154                 128, 128, 128, 128, 128, 128, 128, 128, 
155                 128, 128, 128, 128, 128, 128, 128, 128, 
156                 128, 128, 128, 128, 128, 128, 128, 128, 
157                 128, 128, 128, 128, 128, 128, 128, 128, 
158                 128, 128, 128, 128, 128, 128, 128, 128, 
159                 128, 128, 128, 128, 128, 128, 128, 128, 
160                 128, 128, 128, 128, 128, 128, 128, 128, 
161         };
162         yych = *p;
163         if (yybm[0+yych] & 32) {
164                 goto yy9;
165         }
166         if (yych <= '^') {
167                 if (yych <= ',') {
168                         if (yych <= '\f') {
169                                 if (yych <= 0x00) goto yy2;
170                                 if (yych == '\n') goto yy6;
171                                 goto yy4;
172                         } else {
173                                 if (yych <= '\r') goto yy8;
174                                 if (yych == '#') goto yy12;
175                                 goto yy4;
176                         }
177                 } else {
178                         if (yych <= ':') {
179                                 if (yych == '/') goto yy4;
180                                 if (yych <= '9') goto yy13;
181                                 goto yy16;
182                         } else {
183                                 if (yych <= '=') {
184                                         if (yych <= '<') goto yy4;
185                                         goto yy18;
186                                 } else {
187                                         if (yych <= '@') goto yy4;
188                                         if (yych <= 'Z') goto yy13;
189                                         goto yy4;
190                                 }
191                         }
192                 }
193         } else {
194                 if (yych <= 'i') {
195                         if (yych <= 'b') {
196                                 if (yych == '`') goto yy4;
197                                 if (yych <= 'a') goto yy13;
198                                 goto yy20;
199                         } else {
200                                 if (yych == 'd') goto yy21;
201                                 if (yych <= 'h') goto yy13;
202                                 goto yy22;
203                         }
204                 } else {
205                         if (yych <= 'r') {
206                                 if (yych == 'p') goto yy23;
207                                 if (yych <= 'q') goto yy13;
208                                 goto yy24;
209                         } else {
210                                 if (yych <= 'z') {
211                                         if (yych <= 's') goto yy25;
212                                         goto yy13;
213                                 } else {
214                                         if (yych == '|') goto yy26;
215                                         goto yy4;
216                                 }
217                         }
218                 }
219         }
220 yy2:
221         ++p;
222         { token = TEOF;     break; }
223 yy4:
224         ++p;
225 yy5:
226         { token = ERROR;    break; }
227 yy6:
228         ++p;
229         { token = NEWLINE;  break; }
230 yy8:
231         yych = *++p;
232         if (yych == '\n') goto yy28;
233         goto yy5;
234 yy9:
235         yyaccept = 0;
236         q = ++p;
237         yych = *p;
238         if (yybm[0+yych] & 32) {
239                 goto yy9;
240         }
241         if (yych <= '\f') {
242                 if (yych == '\n') goto yy6;
243         } else {
244                 if (yych <= '\r') goto yy30;
245                 if (yych == '#') goto yy32;
246         }
247 yy11:
248         { token = INDENT;   break; }
249 yy12:
250         yyaccept = 1;
251         yych = *(q = ++p);
252         if (yych <= 0x00) goto yy5;
253         goto yy33;
254 yy13:
255         ++p;
256         yych = *p;
257 yy14:
258         if (yybm[0+yych] & 64) {
259                 goto yy13;
260         }
261         { token = IDENT;    break; }
262 yy16:
263         ++p;
264         { token = COLON;    break; }
265 yy18:
266         ++p;
267         { token = EQUALS;   break; }
268 yy20:
269         yych = *++p;
270         if (yych == 'u') goto yy36;
271         goto yy14;
272 yy21:
273         yych = *++p;
274         if (yych == 'e') goto yy37;
275         goto yy14;
276 yy22:
277         yych = *++p;
278         if (yych == 'n') goto yy38;
279         goto yy14;
280 yy23:
281         yych = *++p;
282         if (yych == 'o') goto yy39;
283         goto yy14;
284 yy24:
285         yych = *++p;
286         if (yych == 'u') goto yy40;
287         goto yy14;
288 yy25:
289         yych = *++p;
290         if (yych == 'u') goto yy41;
291         goto yy14;
292 yy26:
293         ++p;
294         if ((yych = *p) == '|') goto yy42;
295         { token = PIPE;     break; }
296 yy28:
297         ++p;
298         { token = NEWLINE;  break; }
299 yy30:
300         yych = *++p;
301         if (yych == '\n') goto yy28;
302 yy31:
303         p = q;
304         if (yyaccept == 0) {
305                 goto yy11;
306         } else {
307                 goto yy5;
308         }
309 yy32:
310         ++p;
311         yych = *p;
312 yy33:
313         if (yybm[0+yych] & 128) {
314                 goto yy32;
315         }
316         if (yych <= 0x00) goto yy31;
317         ++p;
318         { continue; }
319 yy36:
320         yych = *++p;
321         if (yych == 'i') goto yy44;
322         goto yy14;
323 yy37:
324         yych = *++p;
325         if (yych == 'f') goto yy45;
326         goto yy14;
327 yy38:
328         yych = *++p;
329         if (yych == 'c') goto yy46;
330         goto yy14;
331 yy39:
332         yych = *++p;
333         if (yych == 'o') goto yy47;
334         goto yy14;
335 yy40:
336         yych = *++p;
337         if (yych == 'l') goto yy48;
338         goto yy14;
339 yy41:
340         yych = *++p;
341         if (yych == 'b') goto yy49;
342         goto yy14;
343 yy42:
344         ++p;
345         { token = PIPE2;    break; }
346 yy44:
347         yych = *++p;
348         if (yych == 'l') goto yy50;
349         goto yy14;
350 yy45:
351         yych = *++p;
352         if (yych == 'a') goto yy51;
353         goto yy14;
354 yy46:
355         yych = *++p;
356         if (yych == 'l') goto yy52;
357         goto yy14;
358 yy47:
359         yych = *++p;
360         if (yych == 'l') goto yy53;
361         goto yy14;
362 yy48:
363         yych = *++p;
364         if (yych == 'e') goto yy55;
365         goto yy14;
366 yy49:
367         yych = *++p;
368         if (yych == 'n') goto yy57;
369         goto yy14;
370 yy50:
371         yych = *++p;
372         if (yych == 'd') goto yy58;
373         goto yy14;
374 yy51:
375         yych = *++p;
376         if (yych == 'u') goto yy60;
377         goto yy14;
378 yy52:
379         yych = *++p;
380         if (yych == 'u') goto yy61;
381         goto yy14;
382 yy53:
383         ++p;
384         if (yybm[0+(yych = *p)] & 64) {
385                 goto yy13;
386         }
387         { token = POOL;     break; }
388 yy55:
389         ++p;
390         if (yybm[0+(yych = *p)] & 64) {
391                 goto yy13;
392         }
393         { token = RULE;     break; }
394 yy57:
395         yych = *++p;
396         if (yych == 'i') goto yy62;
397         goto yy14;
398 yy58:
399         ++p;
400         if (yybm[0+(yych = *p)] & 64) {
401                 goto yy13;
402         }
403         { token = BUILD;    break; }
404 yy60:
405         yych = *++p;
406         if (yych == 'l') goto yy63;
407         goto yy14;
408 yy61:
409         yych = *++p;
410         if (yych == 'd') goto yy64;
411         goto yy14;
412 yy62:
413         yych = *++p;
414         if (yych == 'n') goto yy65;
415         goto yy14;
416 yy63:
417         yych = *++p;
418         if (yych == 't') goto yy66;
419         goto yy14;
420 yy64:
421         yych = *++p;
422         if (yych == 'e') goto yy68;
423         goto yy14;
424 yy65:
425         yych = *++p;
426         if (yych == 'j') goto yy70;
427         goto yy14;
428 yy66:
429         ++p;
430         if (yybm[0+(yych = *p)] & 64) {
431                 goto yy13;
432         }
433         { token = DEFAULT;  break; }
434 yy68:
435         ++p;
436         if (yybm[0+(yych = *p)] & 64) {
437                 goto yy13;
438         }
439         { token = INCLUDE;  break; }
440 yy70:
441         yych = *++p;
442         if (yych != 'a') goto yy14;
443         ++p;
444         if (yybm[0+(yych = *p)] & 64) {
445                 goto yy13;
446         }
447         { token = SUBNINJA; break; }
448 }
449
450   }
451
452   last_token_ = start;
453   ofs_ = p;
454   if (token != NEWLINE && token != TEOF)
455     EatWhitespace();
456   return token;
457 }
458
459 bool Lexer::PeekToken(Token token) {
460   Token t = ReadToken();
461   if (t == token)
462     return true;
463   UnreadToken();
464   return false;
465 }
466
467 void Lexer::EatWhitespace() {
468   const char* p = ofs_;
469   const char* q;
470   for (;;) {
471     ofs_ = p;
472     
473 {
474         unsigned char yych;
475         static const unsigned char yybm[] = {
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                 128,   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                   0,   0,   0,   0,   0,   0,   0,   0, 
489                   0,   0,   0,   0,   0,   0,   0,   0, 
490                   0,   0,   0,   0,   0,   0,   0,   0, 
491                   0,   0,   0,   0,   0,   0,   0,   0, 
492                   0,   0,   0,   0,   0,   0,   0,   0, 
493                   0,   0,   0,   0,   0,   0,   0,   0, 
494                   0,   0,   0,   0,   0,   0,   0,   0, 
495                   0,   0,   0,   0,   0,   0,   0,   0, 
496                   0,   0,   0,   0,   0,   0,   0,   0, 
497                   0,   0,   0,   0,   0,   0,   0,   0, 
498                   0,   0,   0,   0,   0,   0,   0,   0, 
499                   0,   0,   0,   0,   0,   0,   0,   0, 
500                   0,   0,   0,   0,   0,   0,   0,   0, 
501                   0,   0,   0,   0,   0,   0,   0,   0, 
502                   0,   0,   0,   0,   0,   0,   0,   0, 
503                   0,   0,   0,   0,   0,   0,   0,   0, 
504                   0,   0,   0,   0,   0,   0,   0,   0, 
505                   0,   0,   0,   0,   0,   0,   0,   0, 
506                   0,   0,   0,   0,   0,   0,   0,   0, 
507                   0,   0,   0,   0,   0,   0,   0,   0, 
508         };
509         yych = *p;
510         if (yybm[0+yych] & 128) {
511                 goto yy79;
512         }
513         if (yych <= 0x00) goto yy75;
514         if (yych == '$') goto yy82;
515         goto yy77;
516 yy75:
517         ++p;
518         { break; }
519 yy77:
520         ++p;
521 yy78:
522         { break; }
523 yy79:
524         ++p;
525         yych = *p;
526         if (yybm[0+yych] & 128) {
527                 goto yy79;
528         }
529         { continue; }
530 yy82:
531         yych = *(q = ++p);
532         if (yych == '\n') goto yy83;
533         if (yych == '\r') goto yy85;
534         goto yy78;
535 yy83:
536         ++p;
537         { continue; }
538 yy85:
539         yych = *++p;
540         if (yych == '\n') goto yy87;
541         p = q;
542         goto yy78;
543 yy87:
544         ++p;
545         { continue; }
546 }
547
548   }
549 }
550
551 bool Lexer::ReadIdent(string* out) {
552   const char* p = ofs_;
553   const char* start;
554   for (;;) {
555     start = p;
556     
557 {
558         unsigned char yych;
559         static const unsigned char yybm[] = {
560                   0,   0,   0,   0,   0,   0,   0,   0, 
561                   0,   0,   0,   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, 128, 128,   0, 
566                 128, 128, 128, 128, 128, 128, 128, 128, 
567                 128, 128,   0,   0,   0,   0,   0,   0, 
568                   0, 128, 128, 128, 128, 128, 128, 128, 
569                 128, 128, 128, 128, 128, 128, 128, 128, 
570                 128, 128, 128, 128, 128, 128, 128, 128, 
571                 128, 128, 128,   0,   0,   0,   0, 128, 
572                   0, 128, 128, 128, 128, 128, 128, 128, 
573                 128, 128, 128, 128, 128, 128, 128, 128, 
574                 128, 128, 128, 128, 128, 128, 128, 128, 
575                 128, 128, 128,   0,   0,   0,   0,   0, 
576                   0,   0,   0,   0,   0,   0,   0,   0, 
577                   0,   0,   0,   0,   0,   0,   0,   0, 
578                   0,   0,   0,   0,   0,   0,   0,   0, 
579                   0,   0,   0,   0,   0,   0,   0,   0, 
580                   0,   0,   0,   0,   0,   0,   0,   0, 
581                   0,   0,   0,   0,   0,   0,   0,   0, 
582                   0,   0,   0,   0,   0,   0,   0,   0, 
583                   0,   0,   0,   0,   0,   0,   0,   0, 
584                   0,   0,   0,   0,   0,   0,   0,   0, 
585                   0,   0,   0,   0,   0,   0,   0,   0, 
586                   0,   0,   0,   0,   0,   0,   0,   0, 
587                   0,   0,   0,   0,   0,   0,   0,   0, 
588                   0,   0,   0,   0,   0,   0,   0,   0, 
589                   0,   0,   0,   0,   0,   0,   0,   0, 
590                   0,   0,   0,   0,   0,   0,   0,   0, 
591                   0,   0,   0,   0,   0,   0,   0,   0, 
592         };
593         yych = *p;
594         if (yybm[0+yych] & 128) {
595                 goto yy93;
596         }
597         ++p;
598         {
599       last_token_ = start;
600       return false;
601     }
602 yy93:
603         ++p;
604         yych = *p;
605         if (yybm[0+yych] & 128) {
606                 goto yy93;
607         }
608         {
609       out->assign(start, p - start);
610       break;
611     }
612 }
613
614   }
615   last_token_ = start;
616   ofs_ = p;
617   EatWhitespace();
618   return true;
619 }
620
621 bool Lexer::ReadEvalString(EvalString* eval, bool path, string* err) {
622   const char* p = ofs_;
623   const char* q;
624   const char* start;
625   for (;;) {
626     start = p;
627     
628 {
629         unsigned char yych;
630         static const unsigned char yybm[] = {
631                   0,  16,  16,  16,  16,  16,  16,  16, 
632                  16,  16,   0,  16,  16,   0,  16,  16, 
633                  16,  16,  16,  16,  16,  16,  16,  16, 
634                  16,  16,  16,  16,  16,  16,  16,  16, 
635                  32,  16,  16,  16,   0,  16,  16,  16, 
636                  16,  16,  16,  16,  16, 208, 144,  16, 
637                 208, 208, 208, 208, 208, 208, 208, 208, 
638                 208, 208,   0,  16,  16,  16,  16,  16, 
639                  16, 208, 208, 208, 208, 208, 208, 208, 
640                 208, 208, 208, 208, 208, 208, 208, 208, 
641                 208, 208, 208, 208, 208, 208, 208, 208, 
642                 208, 208, 208,  16,  16,  16,  16, 208, 
643                  16, 208, 208, 208, 208, 208, 208, 208, 
644                 208, 208, 208, 208, 208, 208, 208, 208, 
645                 208, 208, 208, 208, 208, 208, 208, 208, 
646                 208, 208, 208,  16,   0,  16,  16,  16, 
647                  16,  16,  16,  16,  16,  16,  16,  16, 
648                  16,  16,  16,  16,  16,  16,  16,  16, 
649                  16,  16,  16,  16,  16,  16,  16,  16, 
650                  16,  16,  16,  16,  16,  16,  16,  16, 
651                  16,  16,  16,  16,  16,  16,  16,  16, 
652                  16,  16,  16,  16,  16,  16,  16,  16, 
653                  16,  16,  16,  16,  16,  16,  16,  16, 
654                  16,  16,  16,  16,  16,  16,  16,  16, 
655                  16,  16,  16,  16,  16,  16,  16,  16, 
656                  16,  16,  16,  16,  16,  16,  16,  16, 
657                  16,  16,  16,  16,  16,  16,  16,  16, 
658                  16,  16,  16,  16,  16,  16,  16,  16, 
659                  16,  16,  16,  16,  16,  16,  16,  16, 
660                  16,  16,  16,  16,  16,  16,  16,  16, 
661                  16,  16,  16,  16,  16,  16,  16,  16, 
662                  16,  16,  16,  16,  16,  16,  16,  16, 
663         };
664         yych = *p;
665         if (yybm[0+yych] & 16) {
666                 goto yy100;
667         }
668         if (yych <= '\r') {
669                 if (yych <= 0x00) goto yy98;
670                 if (yych <= '\n') goto yy103;
671                 goto yy105;
672         } else {
673                 if (yych <= ' ') goto yy103;
674                 if (yych <= '$') goto yy107;
675                 goto yy103;
676         }
677 yy98:
678         ++p;
679         {
680       last_token_ = start;
681       return Error("unexpected EOF", err);
682     }
683 yy100:
684         ++p;
685         yych = *p;
686         if (yybm[0+yych] & 16) {
687                 goto yy100;
688         }
689         {
690       eval->AddText(StringPiece(start, p - start));
691       continue;
692     }
693 yy103:
694         ++p;
695         {
696       if (path) {
697         p = start;
698         break;
699       } else {
700         if (*start == '\n')
701           break;
702         eval->AddText(StringPiece(start, 1));
703         continue;
704       }
705     }
706 yy105:
707         ++p;
708         if ((yych = *p) == '\n') goto yy108;
709         {
710       last_token_ = start;
711       return Error(DescribeLastError(), err);
712     }
713 yy107:
714         yych = *++p;
715         if (yybm[0+yych] & 64) {
716                 goto yy120;
717         }
718         if (yych <= ' ') {
719                 if (yych <= '\f') {
720                         if (yych == '\n') goto yy112;
721                         goto yy110;
722                 } else {
723                         if (yych <= '\r') goto yy115;
724                         if (yych <= 0x1F) goto yy110;
725                         goto yy116;
726                 }
727         } else {
728                 if (yych <= '/') {
729                         if (yych == '$') goto yy118;
730                         goto yy110;
731                 } else {
732                         if (yych <= ':') goto yy123;
733                         if (yych <= '`') goto yy110;
734                         if (yych <= '{') goto yy125;
735                         goto yy110;
736                 }
737         }
738 yy108:
739         ++p;
740         {
741       if (path)
742         p = start;
743       break;
744     }
745 yy110:
746         ++p;
747 yy111:
748         {
749       last_token_ = start;
750       return Error("bad $-escape (literal $ must be written as $$)", err);
751     }
752 yy112:
753         ++p;
754         yych = *p;
755         if (yybm[0+yych] & 32) {
756                 goto yy112;
757         }
758         {
759       continue;
760     }
761 yy115:
762         yych = *++p;
763         if (yych == '\n') goto yy126;
764         goto yy111;
765 yy116:
766         ++p;
767         {
768       eval->AddText(StringPiece(" ", 1));
769       continue;
770     }
771 yy118:
772         ++p;
773         {
774       eval->AddText(StringPiece("$", 1));
775       continue;
776     }
777 yy120:
778         ++p;
779         yych = *p;
780         if (yybm[0+yych] & 64) {
781                 goto yy120;
782         }
783         {
784       eval->AddSpecial(StringPiece(start + 1, p - start - 1));
785       continue;
786     }
787 yy123:
788         ++p;
789         {
790       eval->AddText(StringPiece(":", 1));
791       continue;
792     }
793 yy125:
794         yych = *(q = ++p);
795         if (yybm[0+yych] & 128) {
796                 goto yy129;
797         }
798         goto yy111;
799 yy126:
800         ++p;
801         yych = *p;
802         if (yych == ' ') goto yy126;
803         {
804       continue;
805     }
806 yy129:
807         ++p;
808         yych = *p;
809         if (yybm[0+yych] & 128) {
810                 goto yy129;
811         }
812         if (yych == '}') goto yy132;
813         p = q;
814         goto yy111;
815 yy132:
816         ++p;
817         {
818       eval->AddSpecial(StringPiece(start + 2, p - start - 3));
819       continue;
820     }
821 }
822
823   }
824   last_token_ = start;
825   ofs_ = p;
826   if (path)
827     EatWhitespace();
828   // Non-path strings end in newlines, so there's no whitespace to eat.
829   return true;
830 }