parser.cpp revision ad6741c6f82febee62bbfc439d03654c2cb3ba3e
1#include "parser.h" 2 3int next_token(struct parse_state *state) 4{ 5 char *x = state->ptr; 6 char *s; 7 8 if (state->nexttoken) { 9 int t = state->nexttoken; 10 state->nexttoken = 0; 11 return t; 12 } 13 14 for (;;) { 15 switch (*x) { 16 case 0: 17 state->ptr = x; 18 return T_EOF; 19 case '\n': 20 x++; 21 state->ptr = x; 22 return T_NEWLINE; 23 case ' ': 24 case '\t': 25 case '\r': 26 x++; 27 continue; 28 case '#': 29 while (*x && (*x != '\n')) x++; 30 if (*x == '\n') { 31 state->ptr = x+1; 32 return T_NEWLINE; 33 } else { 34 state->ptr = x; 35 return T_EOF; 36 } 37 default: 38 goto text; 39 } 40 } 41 42textdone: 43 state->ptr = x; 44 *s = 0; 45 return T_TEXT; 46text: 47 state->text = s = x; 48textresume: 49 for (;;) { 50 switch (*x) { 51 case 0: 52 goto textdone; 53 case ' ': 54 case '\t': 55 case '\r': 56 x++; 57 goto textdone; 58 case '\n': 59 state->nexttoken = T_NEWLINE; 60 x++; 61 goto textdone; 62 case '"': 63 x++; 64 for (;;) { 65 switch (*x) { 66 case 0: 67 /* unterminated quoted thing */ 68 state->ptr = x; 69 return T_EOF; 70 case '"': 71 x++; 72 goto textresume; 73 default: 74 *s++ = *x++; 75 } 76 } 77 break; 78 case '\\': 79 x++; 80 switch (*x) { 81 case 0: 82 goto textdone; 83 case 'n': 84 *s++ = '\n'; 85 break; 86 case 'r': 87 *s++ = '\r'; 88 break; 89 case 't': 90 *s++ = '\t'; 91 break; 92 case '\\': 93 *s++ = '\\'; 94 break; 95 case '\r': 96 /* \ <cr> <lf> -> line continuation */ 97 if (x[1] != '\n') { 98 x++; 99 continue; 100 } 101 case '\n': 102 /* \ <lf> -> line continuation */ 103 state->line++; 104 x++; 105 /* eat any extra whitespace */ 106 while((*x == ' ') || (*x == '\t')) x++; 107 continue; 108 default: 109 /* unknown escape -- just copy */ 110 *s++ = *x++; 111 } 112 continue; 113 default: 114 *s++ = *x++; 115 } 116 } 117 return T_EOF; 118} 119