5 virtual const char *Text() const = 0;
16 virtual unsigned Precedence() const = 0;
19 struct CYTokenPostfix :
24 struct CYTokenAssignment :
29 struct CYTokenAccess :
34 struct CYTokenLiteral :
40 struct CYTokenString :
45 struct CYTokenNumber :
55 struct CYTokenIdentifier :
61 virtual const char *Text() const {
81 struct CYTokenQuestion :
86 std::set<const char *, CStringMapLess> OperatorWords_;
100 CYParser(FILE *fin, FILE *fout) :
104 data_(reinterpret_cast<char *>(malloc(capacity_))),
111 // XXX: this will not deconstruct in constructor failures
115 bool ReadLine(const char *prompt) {
117 data_[capacity_ - 1] = ~'\0';
121 fputs(prompt, fout_);
126 if (fgets(data_, capacity_, fin_) == NULL)
130 if (data_[capacity_ - 1] != '\0') {
131 size_ = strlen(data_);
134 if (data_[size_ - 1] == '\n') {
138 } else if (data_[capacity_ - 2] == '\n') {
139 size_ = capacity_ - 2;
143 size_t capacity(capacity_ * 2);
144 char *data(reinterpret_cast<char *>(realloc(data_, capacity)));
145 _assert(data != NULL);
147 size_ = capacity_ - 1;
148 capacity_ = capacity;
149 fgets(data_ + size_, capacity_ - size_, fin_);
156 _finline void ScanRange(const CYRange &range) {
157 while (range[data_[offset_]])
161 CYToken *ParseToken(const char *prompt) {
165 if (offset_ == size_ && (prompt == NULL || !ReadLine(prompt)))
167 next = data_[offset_++];
168 } while (next == ' ' || next == '\t');
171 size_t index(offset_ - 1);
173 if (WordStartRange_[next]) {
174 ScanRange(WordEndRange_);
176 } else if (next == '.') {
177 char after(data_[offset_]);
178 if (after >= '0' && after <= '9')
181 } else if (next >= '0' && next <= '9') {
183 ScanRange(NumberRange_);
184 type = CYTokenLiteral;
185 } else if (PunctuationRange_[next]) {
187 ScanRange(PunctuationRange_);
188 type = CYTokenPunctuation;
189 } else if (next == '"' || next == '\'') {
191 char after(data_[offset_++]);
193 after = data_[offset_++];
194 _assert(after != '\0');
197 _assert(offset_ < size_);
199 } else if (after == next)
203 type = CYTokenLiteral;
204 } else if (next == '(' || next == '{' || next == '[') {
206 } else if (next == ')' || next == '}' || next == ']') {
208 } else if (next == ';') {
209 type = CYTokenSemiColon;
211 printf(":( %u\n", next);
215 char *value(pool_(data_ + index, offset_ - index));
217 if (type == CYTokenWord && OperatorWords_.find(value) != OperatorWords_.end())
218 type = CYTokenPunctuation;
220 CYToken *token(new(pool_) CYToken());
222 token->value_ = value;
223 token->next_ = token;
224 token->prev_ = &token->next_;
228 CYToken *ParseExpression(const char *prompt) {
229 CYToken *token(ParseToken(prompt));