comparison anagram/agcore/ftpar.cpp @ 0:13d2b8934445

Import AnaGram (near-)release tree into Mercurial.
author David A. Holland
date Sat, 22 Dec 2007 17:52:45 -0500
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:13d2b8934445
1 /*
2 * AnaGram, A System for Syntax Directed Programming
3 * Copyright 1993-2002 Parsifal Software. All Rights Reserved.
4 * See the file COPYING for license and usage terms.
5 *
6 * ftpar.cpp
7 */
8
9 #include "agarray.h"
10 #include "arrays.h"
11 #include "bpe3.h"
12 #include "cd.h"
13 #include "config.h"
14 #include "csexp.h"
15 #include "dict.h"
16 #include "ftpar.h"
17 #include "keyword.h"
18 #include "q1glbl.h"
19 #include "rule.h"
20 #include "token.h"
21 #include "tsd.h"
22
23 //#define INCLUDE_LOGGING
24 #include "log.h"
25
26
27 AgArray<unsigned> traceCounts;
28
29 //static dc_ref trace_count_display;
30
31
32 int precedes(cint a, cint b) {
33 if (a.y < b.y) return 1;
34 if (a.y > b.y) return 0;
35 if (a.x < b.x) return 1;
36 return 0;
37 }
38
39
40 FtParser::FtParser(AgString t)
41 : text(t)
42 , state(t.pointer())
43 , initialStack(0)
44 , lookAhead(state.pointer)
45 , endPointer(state.pointer +
46 (state.pointer != 0 ? strlen((const char *) state.pointer) : 0))
47 , inputToken(0)
48 , nNullShifts(0)
49 , processState(ready)
50 , ruleToReduce(0)
51 , reductionSelection(0)
52 , stackChanged(*this)
53 , testingKeyword(0)
54 {
55 LOGSECTION("FtParser::FtParser");
56 LOGV((int) state.pointer);
57 LOGV((int) lookAhead);
58 getToken();
59 if (!traceCounts.exists()) {
60 traceCounts = AgArray<unsigned>(nforms_base + 1);
61 memset(traceCounts.pointer(), 0, sizeof(unsigned)*traceCounts.size());
62 /*
63 trace_count_display =
64 dc_ref(new rule_count_dc("Trace Coverage", traceCounts));
65 */
66 }
67 }
68
69 FtParser::FtParser()
70 : initialStack(0)
71 , lookAhead(0)
72 , inputToken(0)
73 , nNullShifts(0)
74 , processState(ready)
75 , ruleToReduce(0)
76 , reductionSelection(0)
77 , stackChanged(*this)
78 , testingKeyword(0)
79 {
80 LOGSECTION("FtParser::FtParser");
81 LOGV((int) state.pointer);
82 LOGV((int) lookAhead);
83 if (!traceCounts.exists()) {
84 traceCounts = AgArray<unsigned>(nforms_base + 1);
85 memset(traceCounts.pointer(), 0, sizeof(unsigned)*traceCounts.size());
86 /*
87 trace_count_display =
88 dc_ref(new rule_count_dc("Trace Coverage", traceCounts));
89 */
90 }
91 }
92
93 FtParser::FtParser(tsd *initialStack_)
94 : initialStack(initialStack_ ? copy_tuple_set(initialStack_) : 0)
95 , lookAhead(0)
96 , inputToken(0)
97 , nNullShifts(0)
98 , processState(ready)
99 , ruleToReduce(0)
100 , reductionSelection(0)
101 , stackChanged(*this)
102 , testingKeyword(0)
103 {
104 LOGSECTION("FtParser::FtParser");
105 LOGV((int) state.pointer);
106 LOGV((int) lookAhead);
107 LOGV((int) initialStack);
108 if (initialStack) {
109 LOGV(initialStack->nt);
110 for (unsigned i = 0; i < initialStack->nt; i++) {
111 unsigned sn, tn;
112 xtx(initialStack,i, &sn, &tn);
113 stateStack.push(State(sn,tn));
114 }
115 state = stateStack.pop();
116 }
117 LOGV(stateStack.size());
118 if (!traceCounts.exists()) {
119 traceCounts = AgArray<unsigned>(nforms_base + 1);
120 memset(traceCounts.pointer(), 0, sizeof(unsigned)*traceCounts.size());
121 /*
122 trace_count_display =
123 dc_ref(new rule_count_dc("Trace Coverage", traceCounts));
124 */
125 }
126 }
127
128 FtParser::~FtParser() {
129 if (initialStack) {
130 delete_tsd(initialStack);
131 }
132 }
133
134 FtParser &FtParser::reset() {
135 LOGSECTION("FtParser::reset");
136 stateStack.discardData();
137 auxStack.discardData();
138 transStack.discardData();
139 LOGV(auxStack.size());
140 LOGV((int) initialStack);
141 inputToken = 0;
142 if (initialStack) {
143 LOGV(initialStack->nt);
144 for (unsigned i = 0; i < initialStack->nt; i++) {
145 unsigned sn, tn;
146 xtx(initialStack,i, &sn, &tn);
147 stateStack.push(State(sn, tn));
148 }
149 state = stateStack.pop();
150 }
151 else {
152 state = State(text.pointer());
153 lookAhead = state.pointer;
154 endPointer = state.pointer +
155 (state.pointer != 0 ? strlen((const char *) state.pointer) : 0);
156 getToken();
157 }
158 LOGV(stateStack.size());
159 reductionState = State();
160 nNullShifts = 0;
161 processState = ready;
162 //if ((dc *)displayControl) {
163 // displayControl->des->d_size.y = stateStack.size();
164 //}
165 stackChanged(stateStack.size() + 1);
166 return *this;
167 }
168
169 void FtParser::track(void) {
170 LOGSECTION("FtParser::track");
171 LOGV((int) state.pointer);
172 LOGV((int) lookAhead);
173 if (lookAhead != 0) {
174 while (state.pointer < lookAhead) {
175 switch (*state.pointer++) {
176 case '\n':
177 if (*state.pointer) state.column = state.charPos = 0, state.line++;
178 case '\f':
179 break;
180 case '\t':
181 state.column += tab_spacing - state.column % tab_spacing;
182 state.charPos++;
183 break;
184 default:
185 state.column++;
186 state.charPos++;
187 }
188 }
189 }
190 state.token = inputToken = 0;
191 auxStack.discardData();
192 transStack.discardData();
193 LOGV(auxStack.size());
194 nNullShifts = 0;
195 LOGV(state.line) LCV(state.column);
196 }
197
198 void FtParser::shiftTerminalAndAccept(void) {
199 LOGSECTION("FtParser::shiftTerminalAndAccept");
200 processState = finished;
201 track();
202 }
203
204 void FtParser::shiftTerminal() {
205 LOGSECTION("FtParser::shiftTerminal");
206 LOGV(state.number) LCV(state.token) LCV((int) state.pointer);
207 LOGV(stateStack.size());
208 state.token = map_state_number[actionParameter].char_token;
209 stateStack.push(state);
210 state.number = actionParameter;
211 track();
212 LOGV(state.token);
213 LOGV(state.number) LCV((int) state.pointer);
214 LOGV(stateStack.size());
215 }
216
217 void FtParser::requestSelection(int actionParameter) {
218 LOGSECTION("FtParser::requestSelection");
219 processState = selectionRequired;
220 ruleToReduce = actionParameter;
221 reductionSelection = 0;
222 while (!validSelection(reductionSelection, reductionState.number)) {
223 reductionSelection++;
224 }
225 LOGV(ruleToReduce);
226 LOGV(reductionIndex);
227 LOGV(state.number) LCV((int) state.pointer);
228 LOGV(reductionState.number);
229 reductionState.token = ibnfs[ibnfb[ruleToReduce]];
230 LOGV(stateStack.size());
231 }
232
233 /*
234 * State stack discipline
235 * reduce
236 * If n is the length of the rule, n states are popped from the
237 * state stack.
238 * If n > 0, the state number becomes the state number of the
239 * last state popped.
240 *
241 * shiftTerminalAndReduce
242 * If n is the length of the rule, n-1 states are popped from
243 * the state stack.
244 * If n > 1, the state number becomes the state number of the
245 * last state popped.
246 *
247 * shiftNonterminalAndReduce
248 * If n is the length of the rule, n-1 states are popped from
249 * the state stack.
250 * If n > 1, the state number becomes the state number of the
251 * last state popped.
252 *
253 * shiftNull
254 * The current state is pushed to the state stack and the
255 * new state number is given by the action parameter.
256 *
257 * shiftNonterminal
258 * The current state is pushed to the state stack and the
259 * new state number is given by the action parameter
260 */
261
262 void FtParser::shiftTerminalAndReduce() {
263 LOGSECTION("FtParser::shiftTerminalAndReduce");
264 LOGV(state.number) LCV(state.token) LCV((int) state.pointer);
265 LOGV(location());
266 LOGV(actionParameter);
267 //form_number_map *fp = &map_form_number[actionParameter];
268 Rule rule(actionParameter);
269 RuleDescriptor &ruleDescriptor(rule);
270 //ruleLength = rule->length();
271 ruleLength = ruleDescriptor.length();
272 LOGV(ruleLength);
273 if (actionParameter <= nforms_base) {
274 traceCounts[actionParameter]++;
275 }
276 int nStackedStates = ruleLength - 1;
277 if (nStackedStates > 0) {
278 reductionState = stateStack[stateStack.size() - nStackedStates];
279 }
280 else {
281 reductionState = state;
282 }
283 track();
284 if (ibnfn[actionParameter] > 1) {
285 reductionIndex = stateStack.size() - (ruleLength - 1);
286 assert((unsigned) reductionIndex <= (unsigned) stateStack.size());
287 requestSelection(actionParameter);
288 return;
289 }
290 assert((unsigned)nStackedStates <= stateStack.size());
291 stateStack.discardData(nStackedStates);
292 //reductionState.token = rule->prim_tkn;
293 reductionState.token = ruleDescriptor.prim_tkn;
294 state.number = reductionState.number;
295 dispatchReductionToken();
296 LOGV(location());
297 LOGV(state.number);
298 LOGV(state.token) LCV((int) state.pointer);
299 auxStack.discardData();
300 transStack.discardData();
301 LOGV(auxStack.size());
302 }
303
304 void FtParser::reduce(void) {
305 LOGSECTION("FtParser::reduce");
306 LOGV(state.number) LCV(state.token) LCV((int) state.pointer);
307 //form_number_map *fp = &map_form_number[actionParameter];
308 Rule rule(actionParameter);
309 RuleDescriptor &ruleDescriptor(rule);
310 //ruleLength = rule->length();
311 ruleLength = ruleDescriptor.length();
312 LOGV(actionParameter);
313 LOGV(ruleLength);
314 LOGV(stateStack.size());
315 if (actionParameter <= nforms_base) {
316 traceCounts[actionParameter]++;
317 }
318 if (ruleLength) {
319 reductionState = stateStack[stateStack.size() - ruleLength];
320 }
321 else {
322 reductionState = state;
323 }
324 if (ibnfn[actionParameter] > 1) {
325 reductionIndex = stateStack.size() - ruleLength;
326 assert((unsigned) reductionIndex <= (unsigned) stateStack.size());
327 requestSelection(actionParameter);
328 return;
329 }
330 int k = ruleLength;
331 transStack.push(Transaction(k, state));
332 LOGV(transStack.size());
333 LOGV(k) LCV(state.number) LCV(state.token);
334 LOGV(nNullShifts);
335 while (k--) {
336 LOGV(stateStack.top().number) LCV(stateStack.top().token)
337 LCV((int) state.pointer);
338 auxStack.push(stateStack.pop());
339 }
340 LOGV(auxStack.size());
341 //reductionState.token = rule->prim_tkn;
342 reductionState.token = ruleDescriptor.prim_tkn;
343 state.number = reductionState.number;
344 LOGV(reductionState.token);
345 LOGV(stateStack.size());
346 dispatchReductionToken();
347 LOGV(stateStack.size());
348 if (lookAhead) {
349 lookAhead = state.pointer;
350 }
351 state.token = 0;
352 }
353
354 void FtParser::skip(void) {
355 LOGSECTION("FtParser::skip");
356 LOGV(state.number) LCV(state.token);
357 if (actionParameter <= nforms_base) {
358 traceCounts[actionParameter]++;
359 }
360 track();
361 }
362
363 void FtParser::shiftNull(void) {
364 LOGSECTION("FtParser::shiftNull");
365 LOGV(state.number) LCV(state.token) LCV((int) state.pointer);
366 transStack.push(Transaction(-1, state));
367 LOGV(transStack.size());
368 state.token = map_state_number[actionParameter].char_token;
369 stateStack.push(state);
370 state.number = actionParameter;
371 if (lookAhead) {
372 lookAhead = state.pointer;
373 }
374 state.token = 0;
375 }
376
377 void FtParser::error() {
378 LOGSECTION("FtParser::error");
379 LOGV(stateStack.size());
380 LOGV(state.number) LCV(state.token) LCV((int) state.pointer);
381 LOGV(state.number) LCV(state.token) LCV((int) state.pointer);
382 LOGV(auxStack.size());
383 int k = transStack.size();
384 LOGV(transStack.size());
385 while (k--) {
386 Transaction trans = transStack.pop();
387 int n = trans.count;
388 LOGV(trans.count) LCV(trans.state.number) LCV(trans.state.token);
389 while (n < 0) {
390 stateStack.pop();
391 n++;
392 }
393 while (n > 0) {
394 stateStack.push(auxStack.pop());
395 n--;
396 }
397 state.number = trans.state.number;
398 state.token = trans.state.token;
399 LOGV(trans.count) LCV(state.number) LCV(state.token);
400 }
401 auxStack.discardData();
402 transStack.discardData();
403 processState = syntaxError;
404 if (lookAhead) {
405 lookAhead = state.pointer;
406 }
407 state.token = 0;
408 }
409
410
411 void FtParser::accept(void) {
412 LOGSECTION("FtParser::accept");
413 state.number = stateStack.top().number;
414 state.token = stateStack.top().token;
415 stateStack.pop();
416 LOGV(stateStack.size());
417 processState = finished;
418 }
419
420 int FtParser::shiftNonterminal() {
421 LOGSECTION("FtParser::shiftNonterminal");
422 LOGV(state.number) LCV(state.token) LCV((int) state.pointer);
423 transStack.push(Transaction(-1, state));
424 LOGV(transStack.size());
425 LOGV(actionParameter) LCV(nstates);
426 reductionState.token = map_state_number[actionParameter].char_token;
427 #ifdef INCLUDE_LOGGING
428 ics();
429 atkn(reductionState.token);
430 LOGV(reductionState.token) LCV(string_base);
431 rcs();
432 #endif
433 stateStack.push(reductionState);
434 state.number = actionParameter;
435 LOGV(stateStack.size());
436 LOGV(state.number) LCV((int) state.pointer);
437 return 0;
438 }
439
440 int FtParser::shiftNonterminalAndReduce() {
441 LOGSECTION("FtParser::shiftNonterminalAndReduce");
442 LOGV(location());
443 LOGV(reductionState.number) LCV(reductionState.token);
444 //form_number_map *fp = &map_form_number[actionParameter];
445 Rule rule(actionParameter);
446 RuleDescriptor &ruleDescriptor(rule);
447 //ruleLength = rule->length();
448 ruleLength = ruleDescriptor.length();
449 LOGS("rule number") LCV(actionParameter);
450 LOGV(ruleLength);
451 LOGV(rule->prim_tkn);
452 LOGV(stateStack.size());
453 if (actionParameter <= nforms_base) {
454 traceCounts[actionParameter]++;
455 }
456 int nStackedStates = ruleLength - 1;
457 if (nStackedStates > 0) {
458 reductionState = stateStack[stateStack.size() - nStackedStates];
459 }
460 if (ibnfn[actionParameter] > 1) {
461 reductionIndex = stateStack.size() - (ruleLength - 1);
462 assert((unsigned) reductionIndex <= (unsigned) stateStack.size());
463 requestSelection(actionParameter);
464 return 0;
465 }
466 transStack.push(Transaction(nStackedStates, state));
467 LOGV(transStack.size());
468 LOGV(nStackedStates) LCV(state.number) LCV(state.token);
469 LOGV(auxStack.size());
470 while (nStackedStates--) {
471 LOGV(stateStack.top().number) LCV(stateStack.top().token)
472 LCV((int) state.pointer);
473 auxStack.push(stateStack.pop());
474 }
475 LOGV(auxStack.size());
476 //reductionState.token = rule->prim_tkn;
477 reductionState.token = ruleDescriptor.prim_tkn;
478 state.number = reductionState.number;
479 LOGV(location());
480 LOGV(stateStack.size());
481 return 1;
482 }
483
484 int FtParser::shiftNonterminalAndAccept() {
485 LOGSECTION("FtParser::shiftNonTerminalAndAccept");
486 state.number = reductionState.number;
487 state.token = reductionState.token;
488 LOGV(state.number);
489 LOGV(state.token) LCV((int) state.pointer);
490 processState = finished;
491 return 0;
492 }
493
494 int (FtParser::*FtParser::nonterminalAction[4])() = {
495 &FtParser::shiftNonterminalAndAccept,
496 &FtParser::shiftNonterminal,
497 &FtParser::shiftNonterminalAndReduce,
498 &FtParser::shiftNonterminalAndReduce
499 };
500
501 void (FtParser::*FtParser::terminalAction[11])() = {
502 &FtParser::shiftTerminalAndAccept,
503 &FtParser::shiftTerminal,
504 &FtParser::shiftTerminalAndReduce,
505 &FtParser::shiftTerminalAndReduce,
506 &FtParser::reduce,
507 &FtParser::reduce,
508 &FtParser::accept,
509 &FtParser::error,
510 &FtParser::shiftNull,
511 &FtParser::skip,
512 &FtParser::skip
513 };
514
515 static int different(const unsigned char *s1, const unsigned char *s2, unsigned n) {
516 LOGSECTION("different");
517 LOGV(n);
518 //if (n > strlen((const char *)s2)) return 1;
519 if (case_sensitive) {
520 return strncmp((const char *)s1, (const char *) s2, n);
521 }
522 while (n--) {
523 if (agToUpper(*s1++) != agToUpper(*s2++)) {
524 return 1;
525 }
526 }
527 return 0;
528 }
529
530
531 Token FtParser::keyToken(void) {
532 LOGSECTION("FtParser::keyToken");
533 int matchLength = 0;
534 //int key = 0;
535 Keyword key;
536 int keyListNumber = map_state_number[state.number].key_list;
537 if (keyListNumber == 0) {
538 return Token();
539 }
540
541 int *keyList = dict_str(key_list_dict, keyListNumber);
542 int nKeys = *keyList++ - 1;
543 LOGV(lookAhead) LCV(nKeys);
544 while (nKeys--) {
545 Keyword keyNumber = map_token_number[*keyList++].key;
546 KeywordDescriptor &keyDescriptor(keyNumber);
547 //unsigned char *keyString = (unsigned char *)keyNumber->string.pointer();
548 unsigned char *keyString = (unsigned char *)keyDescriptor.string.pointer();
549 //AgString keyString = keyNumber->string;
550 int length = strlen((const char *) keyString);
551 //int length = keyString.size();
552 if (length <= matchLength) {
553 continue;
554 }
555 if ((lookAhead + length) > endPointer) {
556 continue;
557 }
558 if (different(keyString, lookAhead, length)) {
559 continue;
560 }
561 //if (different((unsigned char *)keyString.pointer(), lookAhead, length)) {
562 // continue;
563 //}
564 //int charSetNumber = keyNumber->reserve;
565 int charSetNumber = keyDescriptor.reserve;
566 if (charSetNumber) {
567 int *reservedCharSet = dict_str(char_set_dict, charSetNumber);
568 int nReservedCharSet = *reservedCharSet++ - 1;
569 if (lookAhead + length < endPointer) {
570 unsigned char fc = state.pointer[length];
571 while (nReservedCharSet && fc != *reservedCharSet++) {
572 nReservedCharSet--;
573 }
574 if (nReservedCharSet) {
575 continue;
576 }
577 }
578 }
579 matchLength = length;
580 key = keyNumber;
581 }
582 LOGV((int) lookAhead) LCV(matchLength);
583 LOGV(key) LCV(testingKeyword);
584 if (key.isNotNull() && (int) key != testingKeyword) {
585 lookAhead = state.pointer + matchLength;
586 LOGV(key->token_number);
587 return key->token_number;
588 }
589 return Token();
590 }
591
592
593 void FtParser::getToken() {
594 LOGSECTION("FtParser::getToken");
595 LOGV(stateStack.size());
596 LOGV(state.number) LCV((int) state.pointer);
597 LOGV((int) lookAhead);
598 LOGV((int) endPointer);
599 LOGV(inputToken);
600 if (inputToken) {
601 state.token = inputToken;
602 }
603 else if (lookAhead != 0 && lookAhead >= endPointer) {
604 if (text.exists() && eof_token) {
605 token_number_map &eofTokenMap = map_token_number[eof_token];
606 //if (map_token_number[eof_token].non_terminal_flag) {
607 if (eofTokenMap.non_terminal_flag) {
608 //unsigned charSet = map_token_number[eof_token].token_set_id;
609 unsigned charSet = eofTokenMap.token_set_id;
610 unsigned *list = (unsigned *) dict_str(char_set_dict,charSet);
611 int character = list[1];
612 LOGV(charSet);
613 LOGV(character);
614 state.token = map_char_number[character].token_number;
615 }
616 else {
617 state.token = eof_token;
618 }
619 LOGV(state.token) LCV((int) state.pointer);
620 }
621 else {
622 processState = unexpectedEndOfFile;
623 state.token = 0;
624 }
625 }
626 else if (lookAhead != 0) {
627 state.token = keyToken();
628 LOGV(state.token) LCV((int) state.pointer);
629 if (state.token == 0) {
630 state.token =
631 map_char_number[*lookAhead++ - min_char_number].token_number;
632 }
633 }
634 LOGV(state.token) LCV((int) state.pointer);
635 LOGV(auxStack.size());
636 }
637
638 /*
639 unsigned FtParser::inspectToken() {
640 LOGSECTION("FtParser::inspectToken");
641 LOGV((int) lookAhead);
642 LOGV((int) endPointer);
643 unsigned token = 0;
644 if (inputToken) {
645 token = inputToken;
646 }
647 else if (lookAhead !=0 && lookAhead >= endPointer) {
648 if (text.exists() && eof_token) {
649 if (map_token_number[eof_token].non_terminal_flag) {
650 unsigned charSet = map_token_number[eof_token].token_set_id;
651 unsigned *list = (unsigned *) dict_str(char_set_dict,charSet);
652 int character = list[1];
653 LOGV(charSet);
654 LOGV(character);
655 token = map_char_number[character].token_number;
656 }
657 else {
658 token = eof_token;
659 }
660 LOGV(token);
661 }
662 else {
663 token = 0;
664 }
665 }
666 else if (lookAhead != 0) {
667 const unsigned char *save = lookAhead;
668 token = keyToken();
669 lookAhead = save;
670 LOGV(token);
671 if (token == 0) {
672 token = map_char_number[*lookAhead - min_char_number].token_number;
673 }
674 }
675 LOGV(token);
676 LOGV(auxStack.size());
677 return token;
678 }
679 */
680
681 void FtParser::dispatchReductionToken() {
682 LOGSECTION("FtParser::dispatchReductionToken");
683 unsigned k;
684 state_number_map *sp;
685
686 do {
687 LOGV(reductionState.number);
688 LOGV(reductionState.token);
689 sp = &map_state_number[reductionState.number];
690 unsigned *tokenPointer = lstptr(*sp,t_actions);
691 for (k = sp->n_actions; k && tokenPointer[--k] != reductionState.token;) {
692 /* nothing */
693 }
694 LOGV(k) LCV(tokenPointer[k]);
695 assert(tokenPointer[k] == reductionState.token);
696 actionParameter = lstptr(*sp,p_actions)[k];
697 LOGV(k) LCV(actionParameter);
698 if (k == 0) {
699 shiftNonterminal();
700 processState = selectionError;
701 stackChanged(stateStack.size()+1);
702 return;
703 }
704 } while ((this->*(nonterminalAction[lstptr(*sp,a_actions)[k]]))());
705 stackChanged(stateStack.size()+1);
706 }
707
708 void FtParser::completeReduction(int token) {
709 LOGSECTION("FtParser::completeReduction(int)");
710 int k = stateStack.size() - reductionIndex;
711 assert((unsigned) k <= (unsigned) stateStack.size());
712 LOGV(k);
713 stateStack.discardData(k);
714 reductionState.token = token;
715 LOGV(token);
716 processState = running;
717 dispatchReductionToken();
718 if (processState == running &&
719 state.pointer == lookAhead &&
720 state.token == 0) {
721 getToken();
722 }
723 nNullShifts = 0;
724 auxStack.discardData();
725 transStack.discardData();
726 LOGV(auxStack.size());
727 }
728
729 void FtParser::completeReduction() {
730 LOGSECTION("FtParser::completeReduction()");
731 int token = ibnfs[ibnfb[ruleToReduce]+reductionSelection];
732 completeReduction(token);
733 }
734
735 void FtParser::parseAction() {
736 LOGSECTION("FtParser::parseAction");
737 state_number_map *sp = &map_state_number[state.number];
738 unsigned *tokenPointer = lstptr(*sp, t_actions);
739
740 if (processState < running) {
741 processState = running;
742 }
743 int k = 0;
744 while (tokenPointer[k] != (unsigned) state.token && tokenPointer[k]) {
745 k++;
746 }
747
748 actionParameter = lstptr(*sp, p_actions)[k];
749 ((*this).*( terminalAction[lstptr(*sp, a_actions)[k]] ))();
750
751 if (processState <= running && state.token == 0) {
752 getToken();
753 }
754 stackChanged(stateStack.size()+1);
755 }
756
757 void FtParser::stepToken(unsigned token) {
758 LOGSECTION("FtParser::stepToken");
759 LOGV(state.number);
760 LOGV(state.token) LCV((int) state.pointer);
761 lookAhead = state.pointer = 0;
762 inputToken = token;
763 processState = running;
764
765 if (map_token_number[token].non_terminal_flag) {
766 reductionState = state;
767 reductionState.token = token;
768 state.token = inputToken = 0;
769 dispatchReductionToken();
770 transStack.discardData();
771 auxStack.discardData();
772 if (processState <= running && state.token == 0) {
773 getToken();
774 }
775 stackChanged(stateStack.size());
776 return;
777 }
778 inputToken = token;
779 state_number_map *sp = &map_state_number[state.number];
780 unsigned *tokenPointer = lstptr(*sp, t_actions);
781 state.token = token;
782
783 int k = 0;
784 while(tokenPointer[k] != (unsigned) state.token && tokenPointer[k]) {
785 k++;
786 }
787
788 actionParameter = lstptr(*sp, p_actions)[k];
789 ((*this).*( terminalAction[lstptr(*sp, a_actions)[k]] ))();
790 LOGV(processState) LCV(state.token);
791 if (processState <= running && state.token == 0) {
792 getToken();
793 }
794 stackChanged(stateStack.size()+1);
795 }
796
797 void FtParser::parseToken(unsigned token) {
798 LOGSECTION("FtParser::parseToken");
799 LOGV(state.number) LCV(token);
800 LOGV(state.token) LCV((int) state.pointer);
801 lookAhead = state.pointer = 0;
802 inputToken = token;
803 processState = token ? running : syntaxError;
804 if (processState == syntaxError) {
805 return;
806 }
807
808 if (map_token_number[token].non_terminal_flag) {
809 reductionState = state;
810 reductionState.token = token;
811 state.token = inputToken = 0;
812 dispatchReductionToken();
813 if (processState <= running && state.token == 0) {
814 getToken();
815 }
816 return;
817 }
818 inputToken = state.token = token;
819
820 while (processState <= running && inputToken != 0) {
821 state_number_map *sp = &map_state_number[state.number];
822 unsigned *tokenPointer = lstptr(*sp, t_actions);
823 int k = 0;
824 while(tokenPointer[k] != (unsigned) state.token && tokenPointer[k]) {
825 k++;
826 }
827 LOGV(k) LCV(sp->n_actions);
828 assert((unsigned) k < sp->n_actions);
829 actionParameter = lstptr(*sp, p_actions)[k];
830 ((*this).*( terminalAction[lstptr(*sp, a_actions)[k]] ))();
831 LOGV(processState) LCV(state.token);
832 if (processState <= running && inputToken != 0) {
833 state.token = inputToken;
834 }
835 }
836 if (processState <= running && state.token == 0) {
837 getToken();
838 }
839 stackChanged(stateStack.size()+1);
840 }
841
842
843
844 int FtParser::validToken(unsigned token, unsigned sn) {
845 LOGSECTION("FtParser::validToken");
846 state_number_map *sp = &map_state_number[sn];
847 unsigned *tokenPointer = lstptr(*sp, t_actions);
848
849 int k = 0;
850 while (tokenPointer[k] && tokenPointer[k] != token && tokenPointer[k]) {
851 k++;
852 }
853 if (k == 0 && lstptr(*sp, a_actions)[k] == pe_syn_error) {
854 return 0;
855 }
856 LOGV(sn);
857 LOGV(token);
858 LOGV(k);
859 LOGV(tokenPointer[k]);
860 return 1;
861 }
862
863 int FtParser::validSelection(unsigned selection, unsigned sn) {
864 LOGSECTION("FtParser::validSelection");
865 state_number_map *sp = &map_state_number[sn];
866 unsigned *tokenPointer = lstptr(*sp, t_actions);
867
868 unsigned token = ibnfs[ibnfb[ruleToReduce] + selection];
869
870 int k;
871 for (k = sp->n_actions; k && tokenPointer[--k] != token; ) {
872 LOGV(k);
873 LOGV(tokenPointer[k]);
874 }
875 LOGV(sn);
876 LOGV(token);
877 LOGV(k);
878 LOGV(tokenPointer[k]);
879 return k != 0;
880 }
881
882 FtParser &FtParser::parseTo(unsigned char *target) {
883 LOGSECTION("FtParser::parseTo");
884 int backup = 0;
885 while (stateStack.size() && state.pointer <= target) {
886 stateStack.pop(state);
887 backup = 1;
888 }
889 if (backup) {
890 processState = running;
891 lookAhead = state.pointer;
892 auxStack.discardData();
893 transStack.discardData();
894 LOGV(auxStack.size());
895 nNullShifts = 0;
896 getToken();
897 }
898 else if (processState == finished) {
899 reset();
900 }
901 if (processState < running) {
902 processState = running;
903 }
904 LOGV(state.token) LCV((int) state.pointer);
905 while (processState <= running && state.pointer < target) {
906 parseAction();
907 }
908 //if ((dc *)displayControl) {
909 // displayControl->des->d_size.y = stateStack.size()+1;
910 //}
911 stackChanged(stateStack.size()+1);
912 return *this;
913 }
914
915 FtParser &FtParser::parse() {
916 if (processState < running) {
917 processState = running;
918 }
919 while (processState <= running) {
920 parseAction();
921 }
922 //if ((dc *)displayControl) {
923 // displayControl->des->d_size.y = stateStack.size()+1;
924 //}
925 stackChanged(stateStack.size()+1);
926 return *this;
927 }
928
929 FtParser &FtParser::parse(const char *fragment) {
930 LOGSECTION("FtParser::parse(const char *)");
931 LOGV(fragment);
932 lookAhead = state.pointer = (const unsigned char *) fragment;
933 inputToken = 0;
934 endPointer = (const unsigned char *) fragment + strlen(fragment);
935 getToken();
936 LOGV(processState) LCV(inputToken);
937
938 while (processState <= running) {
939 parseAction();
940 LOGV(state.pointer);
941 }
942 //if ((dc *)displayControl) {
943 // displayControl->des->d_size.y = stateStack.size()+1;
944 //}
945 stackChanged(stateStack.size()+1);
946 if (processState == unexpectedEndOfFile) {
947 processState = ready;
948 }
949 return *this;
950 }
951
952 FtParser &FtParser::prime(const char *fragment) {
953 LOGSECTION("FtParser::parse(const char *)");
954 LOGV(fragment);
955 lookAhead = state.pointer = (const unsigned char *) fragment;
956 endPointer = (const unsigned char *) fragment + strlen(fragment);
957 getToken();
958 LOGV(processState);
959 stackChanged(stateStack.size()+1);
960 return *this;
961 }
962
963 FtParser &FtParser::parseTo(cint *loc) {
964 LOGSECTION("FtParser::parseTo");
965 LOGV(*loc);
966 LOGV(stateStack.size());
967 LOGV(location());
968 int backup = 0;
969 LOGV(processState);
970 while (stateStack.size()
971 && (loc->y < state.line
972 || (loc->y == state.line && loc->x <= state.charPos))) {
973 stateStack.pop(state);
974 backup = 1;
975 }
976 LOGV(*loc) LCV(location());
977 LOGV(precedes(*loc, location()));
978 if (backup) {
979 processState = running;
980 lookAhead = state.pointer;
981 getToken();
982 }
983 else if (precedes(*loc, location())) {
984 reset();
985 }
986 LOGV(backup);
987 LOGV(processState);
988 LOGV(stateStack.size());
989 LOGV(state.number) LCV((int) state.pointer);
990 LOGV(location());
991 if (processState < running) {
992 processState = running;
993 }
994 while (processState == running &&
995 (state.line < loc->y || (state.line == loc->y &&
996 state.charPos < loc->x))) {
997 parseAction();
998 }
999 LOGV(location());
1000 //if ((dc *)displayControl) {
1001 // displayControl->des->d_size.y = stateStack.size()+1;
1002 //}
1003 stackChanged(stateStack.size()+1);
1004 return *this;
1005 }
1006
1007 FtParser &FtParser::step() {
1008 LOGSECTION("FtParser::step");
1009 LOGV(location());
1010 if (processState < running) {
1011 processState = running;
1012 }
1013 if (processState == running) {
1014 parseAction();
1015 }
1016 //if ((dc *)displayControl) {
1017 // displayControl->des->d_size.y = stateStack.size()+1;
1018 //}
1019 stackChanged(stateStack.size()+1);
1020 return *this;
1021 }
1022
1023 FtParser &FtParser::step(char *fragment) {
1024 LOGSECTION("FtParser::step(const char *)");
1025 LOGV(fragment);
1026 lookAhead = state.pointer = (unsigned char *) fragment;
1027 endPointer = (unsigned char *) fragment + strlen(fragment);
1028 getToken();
1029 LOGV(processState);
1030 if (processState <= running) {
1031 parseAction();
1032 }
1033 //if ((dc *)displayControl) {
1034 // displayControl->des->d_size.y = stateStack.size()+1;
1035 //}
1036 stackChanged(stateStack.size()+1);
1037 if (processState <= running && state.token == 0) {
1038 getToken();
1039 }
1040 if (processState == unexpectedEndOfFile) {
1041 processState = ready;
1042 }
1043 return *this;
1044 }
1045
1046 const char *FtParser::processStateText[] = {
1047 "Ready",
1048 "Ready", //running,
1049 "Parse complete", //finished,
1050 "Syntax error", //syntaxError,
1051 "Unexpected end of file", //unexpectedEndOfFile,
1052 "Select reduction token", //selectionRequired
1053 "Selection error"
1054 };
1055
1056 #if 0 /* unused */
1057 tsd *x1x_new(pcb_type *pcb) {
1058 int sx, sn, tn, /*fn,*/ fx;
1059 int *items;
1060 int nitems;
1061 tsd *isl = init_tsd(4);
1062
1063 ok_ptr(pcb);
1064 sn = PCB.s.sn;
1065 tn = PCB.token_number;
1066 if (PCB.exit_flag) {
1067 tn = 0;
1068 }
1069 sx = PCB.ssx;
1070 if (PCB.reduction_token) {
1071 sx -= PCB.rule_length;
1072 }
1073
1074 {
1075 tuple_dict *d;
1076 d = xis(sn);
1077 items = d->text;
1078 nitems = d->nsx;
1079 items += 2*nitems;
1080 while (nitems--) {
1081 fx = *--items;
1082 Rule rule = *--items;
1083 if (tn == 0 ||
1084 fx >= rule->non_vanishing_length ||
1085 rule.token(fx).isExpansionToken(tn)) {
1086 //x2(Rule(fn)->token(fx), tn))
1087 //x2(lstptr(map_form_number[fn],tokens)[fx], tn))
1088 at(isl,sx,sn,(int) rule,fx);
1089 }
1090 }
1091 delete_tuple_dict(d);
1092 }
1093
1094 while (sx-- > 0) {
1095 tuple_dict *d;
1096 tn = map_state_number[sn].char_token;
1097 sn = PCB.ss[sx].sn;
1098 d = xis(sn);
1099 items = d->text;
1100 nitems = d->nsx;
1101 items += 2*nitems;
1102 while (nitems--) {
1103 fx = *--items;
1104 Rule rule = *--items;
1105 if (fx >= rule->length()) {
1106 continue;
1107 }
1108 if (x3(isl, sx, (int)rule, fx)) {
1109 at(isl, sx, sn, (int) rule, fx);
1110 }
1111 }
1112 delete_tuple_dict(d);
1113 }
1114 return isl;
1115 }
1116 #endif /* 0 - unused */
1117
1118 tsd *FtParser::x1x_new() {
1119 LOGSECTION("FtParser::x1x_new");
1120 int sx, sn, fn, fx;
1121 tsd *isl = init_tsd(4);
1122
1123 sn = state.number;
1124 Token tn = state.token;
1125 if (processState == selectionRequired) {
1126 sn = reductionState.number;
1127 tn = reductionState.token;
1128 }
1129 else if (processState == syntaxError) {
1130 tn = 0;
1131 }
1132 tuple_dict *d = xis(sn);
1133 int *items = d->text;
1134 int nitems = d->nsx;
1135 items += 2*nitems;
1136 LOGV(state.number);
1137 LOGV(state.token);
1138 LOGV(stateStack.size());
1139 LOGV(processState);
1140 LOGV(ntkns);
1141 sx = stateStack.size();
1142 if (processState == selectionRequired) {
1143 int rx = Rule(ruleToReduce)->length();
1144 int n = stateStack.size();
1145 for (sx = reductionIndex; rx >= 0; rx--) {
1146 int index = sx + rx;
1147 if (index > n) {
1148 continue;
1149 }
1150 if (index < n) {
1151 sn = stateStack[index].number;
1152 }
1153 at(isl, index, sn, ruleToReduce, rx);
1154 }
1155 tuple_dict *d = xis(reductionState.number);
1156 int *items = d->text;
1157 int nitems = d->nsx;
1158 items += 2*nitems;
1159 while (nitems--) {
1160 fx = *--items;
1161 fn = *--items;
1162 LOGV(fn);
1163 LOGV(fx);
1164 if ((unsigned) fx >= Rule(fn)->length()) {
1165 continue;
1166 }
1167 if (x3a(isl, sx, fn, fx)) {
1168 at(isl, sx, sn, fn, fx);
1169 }
1170 }
1171 }
1172 else {
1173 state_number_map *sp = &map_state_number[sn];
1174 unsigned *tokenPointer = lstptr(*sp, t_actions);
1175
1176 unsigned k = 0;
1177 while (tokenPointer[k] &&
1178 tokenPointer[k] != (unsigned) tn && tokenPointer[k]) {
1179 k++;
1180 }
1181 if (k == 0 && lstptr(*sp, a_actions)[k] == pe_syn_error) {
1182 tn = 0;
1183 }
1184 LOGV(k);
1185 LOGV(tn);
1186 LOGV(nitems);
1187 if (tn.isNotNull()) {
1188 while (nitems--) {
1189 fx = *--items;
1190 fn = *--items;
1191 LOGV(fn);
1192 LOGV(fx);
1193 //if (x4(tn, fn)) {
1194 if (tn.isExpansionRule(fn)) {
1195 at(isl, sx, sn, fn, fx);
1196 continue;
1197 }
1198 Rule rule = fn;
1199 if ((unsigned) fx >= rule->length()) {
1200 continue;
1201 }
1202 //if (lstptr(map_form_number[fn],tokens)[fx] == tn) {
1203 // at(isl, sx, sn, fn, fx);
1204 //}
1205 if (rule.token(fx) == tn) {
1206 at(isl, sx, sn, (int) rule, fx);
1207 }
1208 }
1209 LOGV(isl->nt);
1210 for (k = 0; k < sp->n_completed_forms; k++) {
1211 unsigned rule = lstptr(*sp,completed_forms)[k];
1212 LOGV(rule);
1213 at(isl, sx, sn, rule, Rule(rule)->length());
1214 }
1215 LOGV(isl->nt);
1216 if (isl->nt) {
1217 items = d->text;
1218 nitems = d->nsx;
1219 items += 2*nitems;
1220 while (nitems--) {
1221 fx = *--items;
1222 fn = *--items;
1223 LOGV(fn);
1224 LOGV(fx);
1225 if ((unsigned) fx >= Rule(fn)->length()) {
1226 continue;
1227 }
1228 if (x3a(isl, sx, fn, fx)) {
1229 at(isl, sx, sn, fn, fx);
1230 }
1231 }
1232 }
1233 else {
1234 items = d->text;
1235 nitems = d->nsx;
1236 items += 2*nitems;
1237 while (nitems--) {
1238 fx = *--items;
1239 fn = *--items;
1240 LOGV(fn);
1241 LOGV(fx);
1242 at(isl, sx, sn, fn, fx);
1243 }
1244 }
1245 }
1246 else while (nitems--) {
1247 fx = *--items;
1248 fn = *--items;
1249 LOGV(fn);
1250 LOGV(fx);
1251 at(isl, sx, sn, fn, fx);
1252 }
1253 }
1254 LOGV(isl->nt);
1255 LOGV((int) d);
1256 delete_tuple_dict(d);
1257 LOGV(sx);
1258 while (sx-- > 0) {
1259 tuple_dict *d;
1260 tn = stateStack[sx].token;
1261 sn = stateStack[sx].number;
1262 LOGV(sn);
1263 LOGV(tn);
1264 d = xis(sn);
1265 items = d->text;
1266 nitems = d->nsx;
1267 items += 2*nitems;
1268 while (nitems--) {
1269 fx = *--items;
1270 fn = *--items;
1271 LOGV(fn);
1272 LOGV(fx);
1273
1274 if ((unsigned) fx >= Rule(fn)->length()) {
1275 continue;
1276 }
1277 if (x3(isl, sx, fn, fx)) {
1278 at(isl, sx, sn, fn, fx);
1279 }
1280 }
1281 delete_tuple_dict(d);
1282 }
1283 LOGV(isl->nt);
1284 return isl;
1285 }
1286