1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // GoLangGenerator.cc
4 // ------------------
5 // GoLangGenerator implementation module
6 //
7 // Design and Implementation by Bjoern Lemke
8 //
9 // (C)opyright 2000-2018 Bjoern Lemke
10 //
11 // This program is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation; either version 2, or (at your option)
14 // any later version.
15 //
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program; see the file COPYING. If not, write to
23 // the Free Software Foundation, 59 Temple Place - Suite 330,
24 // Boston, MA 02111-1307, USA.
25 //
26 // IMPLEMENTATION MODULE
27 //
28 // Class: GoLangGenerator
29 //
30 // Description: Implementation module for the dragon Go generator
31 //
32 ///////////////////////////////////////////////////////////////////////////////
33
34
35 #include <lfcbase/Exception.h>
36 #include <lfcbase/Chain.h>
37 #include <lfcbase/File.h>
38 #include <lfcbase/Tokenizer.h>
39 #include <lfcbase/ListT.h>
40 #include <lfcbase/SetT.h>
41
42 #define LOADCOUNT 50
43
44 #include "GoLangGenerator.h"
45 #include "Worm.h"
46
GoLangGenerator(const Chain & parserName,ParserMode mode,bool dynamicTable)47 GoLangGenerator::GoLangGenerator(const Chain& parserName, ParserMode mode, bool dynamicTable) : Dragon(parserName, mode, dynamicTable)
48 {
49 }
50
~GoLangGenerator()51 GoLangGenerator::~GoLangGenerator()
52 {
53 }
54
generateCode()55 void GoLangGenerator::generateCode()
56 {
57
58
59 Chain goLangFileName = _parserName + ".go";
60
61 File fout(goLangFileName);
62
63 fout.open(File::WRITE);
64
65 fout << "//\n";
66 fout << "// File: "<< _parserName << ".go\n";
67 fout << "// This code was produced by the dragon parser generator\n";
68 fout << "//\n";
69
70 fout << "package " << _parserName << "\n";
71 fout << "\n";
72 // fout << "import \"fmt\"\n";
73 // fout << "import \"os\"\n";
74
75 fout << "type ParserAction interface {\n";
76
77 Production *pProd = _productionSet.First();
78 while (pProd)
79 {
80 if ( pProd->getAction() )
81 {
82 fout << " " << pProd->getAction() << "()\n";
83 }
84 pProd = _productionSet.Next();
85 }
86
87 fout << " SetTokenList(tokenList []string)\n";
88 fout << " IsReserved() bool\n";
89 fout << " GetAndResetReserved() Token\n";
90 fout << " NextChar() byte\n";
91 fout << " BackChar()\n";
92
93 fout << "}\n";
94 fout << "\n";
95
96 fout << "const (\n";
97 fout << " MAXTOKENLEN int = 100\n";
98 fout << ")\n";
99 fout << "\n";
100
101 fout << "type Symbol int\n";
102 fout << "\n";
103 fout << "const (\n";
104 fout << " Symbol_PROD Symbol = 0\n";
105 fout << " Symbol_TOKEN Symbol = 1\n";
106 fout << " Symbol_NONE Symbol = 2\n";
107 fout << ")\n";
108 fout << "\n";
109
110 fout << "type Token int\n";
111
112 fout << "\n";
113 fout << "const (\n";
114
115 int i = 0;
116 Terminal *pTerm = _terminalSet.First();
117 while (pTerm)
118 {
119 // Token_x Token = 0
120 fout << " Token_" << pTerm->getName() << " Token = " << i << "\n";
121 pTerm = _terminalSet.Next();
122 i++;
123 }
124
125 fout << " Token_ENDTOKEN Token = " << i << "\n";
126 fout << ")\n";
127
128 fout << "\n";
129
130 fout << "//////////////////\n";
131 fout << "// Scanner part //\n";
132 fout << "//////////////////\n";
133 fout << "\n";
134
135 fout << "type ScannerStateType int\n";
136 fout << "\n";
137
138 fout << "const (\n";
139 fout << " ScannerStateType_START ScannerStateType = 0\n";
140 fout << " ScannerStateType_INTERMEDIATE ScannerStateType = 1\n";
141 fout << " ScannerStateType_FINAL ScannerStateType = 2\n";
142 fout << " ScannerStateType_ANY ScannerStateType = 3\n";
143 fout << ")\n";
144 fout << "\n";
145
146 fout << "type ScannerStateEntry struct {\n";
147 fout << " state int\n";
148 fout << " stateType ScannerStateType\n";
149 fout << "}\n";
150 fout << "\n";
151
152 fout << "type ScannerTransEntry struct {\n";
153 fout << " state int\n";
154 fout << " fstate int\n";
155 fout << " c byte\n";
156 fout << "}\n";
157 fout << "\n";
158
159 fout << "type Scanner struct {\n";
160 fout << " tok Token\n";
161 fout << " stateList []ScannerStateEntry\n";
162 fout << " transList []ScannerTransEntry\n";
163 fout << "}\n";
164 fout << "\n";
165
166 fout << "func (s *Scanner) addState(state int, stateType ScannerStateType ) {\n";
167 fout << " s.stateList = append(s.stateList, ScannerStateEntry{ state: state, stateType: stateType })\n";
168 fout << "}\n";
169 fout << "\n";
170
171 fout << "func (s *Scanner) addTrans(state int, c byte, fstate int ) {\n";
172 // fout << " fmt.Printf(\"Adding c = %c\\n\", c)\n";
173 fout << " s.transList = append(s.transList, ScannerTransEntry{ state: state, fstate: fstate, c: c })\n";
174 fout << "}\n";
175 fout << "\n";
176
177 fout << "func (s *Scanner) getStateIndex(state int) int {\n";
178 fout << " i := 0\n";
179 fout << " for i < len(s.stateList) {\n";
180 fout << " if s.stateList[i].state == state {\n";
181 fout << " return i\n";
182 fout << " }\n";
183 fout << " i++\n";
184 fout << " }\n";
185 fout << " return -1\n";
186 fout << "}\n";
187 fout << "\n";
188
189 fout << "func (s *Scanner) getTransIndex(state int, c byte ) int {\n";
190 fout << " i := 0\n";
191 fout << " for i < len(s.transList) {\n";
192 // fout << " fmt.Printf(\"Checking transition State=%d C=%c\\n\", s.transList[i].state, s.transList[i].c)\n";
193 fout << "\n";
194 fout << " if s.transList[i].state == state && s.transList[i].c == c {\n";
195 // fout << " fmt.Println(\"Match \\n\")\n";
196 fout << " return i\n";
197 fout << " }\n";
198 fout << " i++\n";
199 fout << " }\n";
200 // fout << " fmt.Println(\"#### No Match\\n\")\n";
201 fout << " return -1\n";
202 fout << "}\n";
203 fout << "\n";
204
205 fout << "func (s *Scanner) checkPattern( pattern string ) bool {\n";
206 // fout << " fmt.Println(\"CHECKING Pattern\")\n";
207 fout << " state := 0\n";
208 fout << " i := 0\n";
209 fout << " for i < len(s.stateList) {\n";
210 fout << " ss := s.stateList[i]\n";
211 fout << " if ss.stateType == ScannerStateType_START || ss.stateType == ScannerStateType_ANY {\n";
212 fout << " state = ss.state\n";
213 fout << " }\n";
214 fout << " i++\n";
215 fout << " }\n";
216 fout << " i = 0\n";
217 // fout << " fmt.Printf(\"state = %d, c = %c\\n\", i, pattern[i])\n";
218 fout << " trsidx := s.getTransIndex ( state, pattern[i] )\n";
219 fout << " if trsidx >= 0 {\n";
220 // fout << " fmt.Println(\"Found transindex %d\\n\", trsidx)\n";
221 fout << " for {\n";
222 fout << " trans := s.transList[trsidx]\n";
223 fout << " statidx := s.getStateIndex(trans.fstate)\n";
224 fout << " if statidx >= 0 {\n";
225 fout << " stateEntry := s.stateList[statidx]\n";
226 fout << " if i == len(pattern) - 1 && ( stateEntry.stateType == ScannerStateType_FINAL || stateEntry.stateType == ScannerStateType_ANY ) {\n";
227 fout << " return true\n";
228 fout << " } else {\n";
229 fout << " state = trans.fstate\n";
230 fout << " }\n";
231 fout << " } else {\n";
232 fout << " return false\n";
233 fout << " }\n";
234 fout << " i++\n";
235 fout << " trsidx = s.getTransIndex ( state, pattern[i] )\n";
236 fout << " if trsidx >= 0 {\n";
237 fout << " trans = s.transList[trsidx]\n";
238 fout << " } else {\n";
239 fout << " return false\n";
240 fout << " }\n";
241 fout << " }\n";
242 fout << " } else {\n";
243 fout << " return false\n";
244 fout << " }\n";
245 fout << "}\n";
246 fout << "\n";
247
248 fout << "/////////////////\n";
249 fout << "// Parser part //\n";
250 fout << "/////////////////\n";
251 fout << "\n";
252 fout << "type Production int\n";
253
254 // filter out distinct production symbols
255
256 SetT<Chain> symbolSet;
257
258 pProd = _productionSet.First();
259 while (pProd)
260 {
261 symbolSet.Insert(pProd->getName());
262 pProd = _productionSet.Next();
263 }
264
265 fout << "const (\n";
266 Chain* pSymbol = symbolSet.First();
267 i = 0;
268 while (pSymbol)
269 {
270 fout << " Production_" << *pSymbol << " Production = " << i << "\n";
271 pSymbol = symbolSet.Next();
272 i++;
273 }
274 fout << ")\n";
275 fout << "\n";
276
277 fout << "type ParserStateAction int\n";
278 fout << "const (\n";
279 fout << " ParserStateAction_SHIFT ParserStateAction = 0\n";
280 fout << " ParserStateAction_REDUCE ParserStateAction = 1\n";
281 fout << " ParserStateAction_ACCEPT ParserStateAction = 2\n";
282 fout << ")\n";
283 fout << "\n";
284
285 fout << "type ParserActionEntry struct {\n";
286 fout << " state int\n";
287 fout << " token Token\n";
288 fout << " action ParserStateAction\n";
289 fout << " num int\n";
290 fout << "}\n";
291 fout << "\n";
292
293 fout << "type ParserJumpEntry struct {\n";
294 fout << " state int\n";
295 fout << " prod Production\n";
296 fout << " fstate int\n";
297 fout << "}\n";
298 fout << "\n";
299
300 fout << "type ProductionEntry struct {\n";
301 fout << " id int\n";
302 fout << " prod Production\n";
303 fout << " numSymbol int\n";
304 fout << "}\n";
305 fout << "\n";
306
307 fout << "type ParserStackEntry struct {\n";
308 fout << " s Symbol\n";
309 fout << " num int\n";
310 fout << " state int\n";
311 fout << " tval string\n";
312 fout << "}\n";
313 fout << "\n";
314
315 fout << "type ParserStack struct {\n";
316 fout << " s []ParserStackEntry\n";
317 fout << "}\n";
318 fout << "\n";
319
320 fout << "func (ps *ParserStack) Push(pse ParserStackEntry) {\n";
321 fout << " ps.s = append(ps.s, pse)\n";
322 fout << "}\n";
323 fout << "\n";
324
325 fout << "func (ps *ParserStack) Pop() ParserStackEntry {\n";
326 fout << " // FIXME: What do we do if the stack is empty, though?\n";
327 fout << " l := len(ps.s)\n";
328 fout << " res := ps.s[l-1]\n";
329 fout << " ps.s = ps.s[:l-1]\n";
330 fout << " return res\n";
331 fout << "}\n";
332 fout << "\n";
333
334 fout << "func (ps *ParserStack) getPeekState() int {\n";
335 fout << " l := len(ps.s)\n";
336 fout << " return ps.s[l-1].state\n";
337 fout << "}\n";
338 fout << "\n";
339
340 fout << "type Parser struct {\n";
341 fout << " act ParserAction\n";
342 fout << " token Token\n";
343 fout << " tokenVal [MAXTOKENLEN]byte\n";
344 fout << " tokenLen int\n";
345 fout << " scannerList []Scanner\n";
346 fout << " actAction ParserStateAction\n";
347 fout << " actNum int\n";
348 fout << " actionMap []ParserActionEntry\n";
349 fout << " jumpMap []ParserJumpEntry\n";
350 fout << " prodMap []ProductionEntry\n";
351 fout << " actFState int\n";
352 fout << " tokenList []string\n";
353 fout << " Error string\n";
354 fout << "}\n";
355 fout << "\n";
356
357 fout << "func (p *Parser) isSepIgnore(c byte) bool {\n";
358
359 Chain* pSep = _sepignoreList.First();
360
361 while (pSep)
362 {
363 fout << " if c == " << *pSep << " { return true }\n";
364 pSep = _sepignoreList.Next();
365 }
366 fout << " return false\n";
367 fout << "}\n";
368 fout << "\n";
369
370 fout << "func (p *Parser) isSepSign(c byte) bool {\n";
371
372 pSep = _sepsignList.First();
373
374 while (pSep)
375 {
376 fout << " if c == " << *pSep << " { return true }\n";
377 pSep = _sepsignList.Next();
378 }
379
380 fout << " return false\n";
381 fout << "}\n";
382 fout << "\n";
383
384 fout << "func (p *Parser) shiftToken() bool {\n";
385 fout << " i := 0\n";
386 fout << " var nb byte\n";
387 fout << " goOn := true\n";
388 fout << " for goOn {\n";
389 fout << " nb = p.act.NextChar()\n";
390 fout << " goOn = p.isSepIgnore(nb) && ! p.act.IsReserved()\n";
391 fout << " }\n";
392 fout << " if p.act.IsReserved() == true {\n";
393 fout << " p.token = p.act.GetAndResetReserved()\n";
394 fout << " return true\n";
395 fout << " }\n";
396 fout << " if nb == 0 {\n";
397 fout << " p.token = Token_ENDTOKEN\n";
398 fout << " return true\n";
399 fout << " }\n";
400 fout << " if p.isSepSign(nb) {\n";
401 fout << " p.tokenVal[i]=nb\n";
402 fout << " i++\n";
403 fout << " } else {\n";
404 fout << " for nb != 0 && ! p.isSepIgnore(nb) && ! ( p.isSepSign(nb) && i>0 ) {\n";
405 fout << " p.tokenVal[i]=nb\n";
406 fout << " i++\n";
407 fout << " nb = p.act.NextChar()\n";
408 fout << " }\n";
409 fout << " if p.isSepSign(nb) {\n";
410 fout << " p.act.BackChar()\n";
411 fout << " }\n";
412 fout << " }\n";
413
414 fout << " p.tokenVal[i]=0\n";
415 fout << " p.tokenLen=i\n";
416
417 fout << " j := 0\n";
418 fout << " for j < len(p.scannerList) {\n";
419 fout << " scan := p.scannerList[j]\n";
420 // fout << " fmt.Printf(\"Check pattern for %s %s\\n\", p.tokenVal, string(p.tokenVal[0:i]))\n";
421
422 fout << " if scan.checkPattern( string(p.tokenVal[0:i]) ) {\n";
423 fout << " p.token = scan.tok\n";
424 fout << " return true\n";
425 fout << " }\n";
426 fout << " j++\n";
427 fout << " }\n";
428 fout << " return false\n";
429 fout << "}\n";
430 fout << "\n";
431
432 fout << "func (p *Parser) getActionIndex(state int, t Token ) int {\n";
433 fout << " for i :=0; i<len(p.actionMap); i++ {\n";
434 fout << " if p.actionMap[i].state == state && p.actionMap[i].token == t {\n";
435 fout << " return i\n";
436 fout << " }\n";
437 fout << " }\n";
438 fout << " return -1\n";
439 fout << "}\n";
440 fout << "\n";
441
442 fout << "func (p *Parser) getProdIndex(id int ) int {\n";
443 fout << " for i :=0; i<len(p.prodMap); i++ {\n";
444 fout << " if p.prodMap[i].id == id {\n";
445 fout << " return i\n";
446 fout << " }\n";
447 fout << " }\n";
448 fout << " return -1\n";
449 fout << "}\n";
450 fout << "\n";
451
452 fout << "func (p *Parser) getAction( state int, token Token) bool {\n";
453 fout << " actidx := p.getActionIndex(state, token)\n";
454 fout << " if actidx >= 0 {\n";
455 fout << " actionEntry := p.actionMap[actidx]\n";
456 fout << " p.actAction = actionEntry.action\n";
457 fout << " p.actNum = actionEntry.num\n";
458 fout << " return true\n";
459 fout << " } else {\n";
460 fout << " return false\n";
461 fout << " }\n";
462 fout << "}\n";
463 fout << "\n";
464
465 fout << "func (p *Parser) getJumpIndex(state int, prod Production ) int {\n";
466 fout << " for i :=0; i<len(p.jumpMap); i++ {\n";
467 fout << " if p.jumpMap[i].state == state && p.jumpMap[i].prod == prod {\n";
468 fout << " return i\n";
469 fout << " }\n";
470 fout << " }\n";
471 fout << " return -1\n";
472 fout << "}\n";
473 fout << "\n";
474
475 fout << "func (p *Parser) getJump( state int, prod Production) bool {\n";
476 fout << " jmpidx := p.getJumpIndex(state, prod)\n";
477 fout << " if jmpidx >= 0 {\n";
478 fout << " jumpEntry := p.jumpMap[jmpidx]\n";
479 fout << " p.actFState = jumpEntry.fstate\n";
480 fout << " return true\n";
481 fout << " } else {\n";
482 fout << " return false\n";
483 fout << " }\n";
484 fout << "}\n";
485 fout << "\n";
486
487 fout << "func (p *Parser) loadScanner() {\n";
488
489 int sid=0;
490
491 for (int i = 1; i<=_terminalSet.Size(); i++)
492 {
493
494 Terminal *pTerm = _terminalSet.First();
495 while (pTerm && pTerm->getNum() != i)
496 {
497 pTerm = _terminalSet.Next();
498 }
499 if (pTerm)
500 {
501
502 Worm w(pTerm->getRegExp(), pTerm->getName());
503
504 w.makeOptimalDEA();
505
506 Chain scanner = "s" + Chain(sid);
507
508 fout << scanner << " := Scanner{ tok: Token_" << pTerm->getName() << "}\n";
509
510 FSMState *pS = w.getStateTable().First();
511 while (pS)
512 {
513
514 fout << " " << scanner << ".addState(" << pS->Num() << " ,";
515
516 switch (pS->Type())
517 {
518 case START:
519 fout << "ScannerStateType_START)\n";
520 break;
521 case FINAL:
522 fout << "ScannerStateType_FINAL)\n";
523 break;
524 case ANY:
525 fout << "ScannerStateType_ANY)\n";
526 break;
527 case NONE:
528 fout << "ScannerStateType_INTERMEDIATE)\n";
529 break;
530 }
531
532 pS = w.getStateTable().Next();
533 }
534
535 FSMTransition *pT = w.getTransitionTable().First();
536
537 while (pT)
538 {
539 fout << " " << scanner << ".addTrans(" << pT->Source() << " ,'" << pT->Sign() << "' ," << pT->Target() << ")\n";
540 pT = w.getTransitionTable().Next();
541 }
542
543 fout << " p.scannerList = append(p.scannerList, " << scanner << ")\n";
544 fout << "\n";
545 sid++;
546 }
547 }
548
549 fout << "}\n";
550 fout << "\n";
551
552 int mcount = 0;
553 fout << "func (p *Parser) loadParser" + Chain(mcount) + "() {\n";
554 int lcount=0;
555
556 ParseTableEntry *pPTE = _parseTable.First();
557 while (pPTE)
558 {
559 Chain token = pPTE->getToken();
560 if ( token == Chain("$") )
561 token = Chain("ENDTOKEN");
562
563 switch (pPTE->getAction())
564 {
565 case ParseTableEntry::SHIFT:
566 fout << " p.actionMap = append(p.actionMap, ParserActionEntry{"
567 << "state: " << pPTE->getState()
568 << ", token: Token_" << token
569 << ", action: ParserStateAction_SHIFT"
570 << ", num: " << pPTE->getArg() << "})\n";
571 break;
572 case ParseTableEntry::REDUCE:
573 fout << " p.actionMap = append(p.actionMap, ParserActionEntry{"
574 << "state: " << pPTE->getState()
575 << ", token: Token_" << token
576 << ", action: ParserStateAction_REDUCE"
577 << ", num: " << pPTE->getArg() << "})\n";
578 break;
579 case ParseTableEntry::JUMP:
580 fout << " p.jumpMap = append(p.jumpMap, ParserJumpEntry{"
581 << "state: " << pPTE->getState()
582 << ", prod: Production_" << token
583 << ", fstate: " << pPTE->getArg() << "})\n";
584 break;
585 case ParseTableEntry::ACCEPT:
586 fout << " p.actionMap = append(p.actionMap, ParserActionEntry{"
587 << "state: " << pPTE->getState()
588 << ", token: Token_" << token
589 << ", action: ParserStateAction_ACCEPT"
590 << ", num: " << pPTE->getArg() << "})\n";
591 break;
592 }
593 lcount++;
594 pPTE = _parseTable.Next();
595
596 if ( pPTE && lcount == LOADCOUNT )
597 {
598 mcount++;
599 lcount=0;
600 fout << "}\n";
601 fout << "func (p *Parser) loadParser" + Chain(mcount) + "() {\n";
602 }
603 }
604 fout << "}\n";
605 fout << "\n";
606
607 fout << "func (p *Parser) loadProduction() {\n";
608
609 pProd = _productionSet.First();
610 while (pProd)
611 {
612 fout << " p.prodMap = append(p.prodMap, ProductionEntry {"
613 << "id: " << pProd->getId()
614 << ", prod: Production_" << pProd->getName()
615 << ", numSymbol : " << pProd->getMaxPos() << "});\n";
616
617 pProd = _productionSet.Next();
618 }
619 fout << "}\n";
620 fout << "\n";
621
622 fout << "func (p *Parser) Parse () bool {\n";
623 fout << " ps := ParserStack{ s: make([]ParserStackEntry,0)}\n";
624 fout << " ps.Push( ParserStackEntry {\n";
625 fout << " s: Symbol_NONE,\n";
626 fout << " num: 0,\n";
627 fout << " state: 0 ,\n";
628 fout << " tval: \"NONE\" } )\n";
629 fout << " if p.shiftToken() == false {\n";
630 fout << " p.Error = \"Invalid token <\" + string(p.tokenVal[0:p.tokenLen]) + \">\"\n";
631 fout << " return false\n";
632 fout << " } else {\n";
633 fout << " for {\n";
634 // fout << " fmt.Printf(\"Go on parsing : peekState = %d, token = %d\\n\", ps.getPeekState(), p.token)\n";
635 fout << " if p.getAction(ps.getPeekState(), p.token) {\n";
636 fout << " if p.actAction == ParserStateAction_SHIFT {\n";
637 fout << " ps.Push( ParserStackEntry {\n";
638 fout << " s: Symbol_TOKEN,\n";
639 fout << " num: int(p.token),\n";
640 fout << " state: p.actNum,\n";
641 fout << " tval: string(p.tokenVal[0:p.tokenLen]) } )\n";
642 fout << " if p.shiftToken() == false {\n";
643 fout << " p.Error = \"Invalid token <\" + string(p.tokenVal[0:p.tokenLen]) + \">\"\n";
644 fout << " return false\n";
645 fout << " // print error here : invalid token\n";
646 fout << " }\n";
647 fout << " } else if p.actAction == ParserStateAction_REDUCE {\n";
648 fout << " p.tokenList = nil\n";
649 fout << " prodidx := p.getProdIndex(p.actNum)\n";
650 fout << " if prodidx == -1 {\n";
651 fout << " p.Error = \"No production entry found\"\n";
652 fout << " return false\n";
653 fout << " }\n";
654 fout << " for i := 0; i < p.prodMap[prodidx].numSymbol; i++ {\n";
655 fout << " ste := ps.Pop();\n";
656 fout << " if ste.s == Symbol_TOKEN {\n";
657 fout << " p.tokenList = append(p.tokenList, ste.tval)\n";
658 fout << " }\n";
659 fout << " }\n";
660 fout << " if p.getJump ( ps.getPeekState(), p.prodMap[prodidx].prod ) {\n";
661 fout << " ps.Push( ParserStackEntry {\n";
662 fout << " s: Symbol_PROD,\n";
663 fout << " num: p.prodMap[prodidx].id,\n";
664 fout << " state: p.actFState,\n";
665 fout << " tval: string(p.tokenVal[0:p.tokenLen]) } )\n";
666 fout << " } else {\n";
667 fout << " p.Error = \"Cannot reduce after token <\" + string(p.tokenVal[0:p.tokenLen]) + \">\"\n";
668 fout << " return false\n";
669 fout << " }\n";
670 fout << " switch p.actNum {\n";
671 pProd = _productionSet.First();
672 while (pProd)
673 {
674 if ( pProd->getId() != 0 && pProd->getAction() )
675 {
676 fout << " case " << pProd->getId() << ":\n";
677 fout << " p.act.SetTokenList(p.tokenList)\n";
678 fout << " p.act." << pProd->getAction() << "()\n";
679 }
680 pProd = _productionSet.Next();
681 }
682
683 fout << " }\n";
684 fout << " p.tokenList = nil\n";
685 fout << " } else if p.actAction == ParserStateAction_ACCEPT {\n";
686
687 pProd = _productionSet.First();
688 while (pProd)
689 {
690 if ( pProd->getId() == 0 && pProd->getAction() )
691 {
692 fout << " p.act.SetTokenList(p.tokenList)\n";
693 fout << " p.act." << pProd->getAction() << "()\n";
694 }
695 pProd = _productionSet.Next();
696 }
697 fout << " return true\n";
698 fout << " }\n";
699 fout << " } else {\n";
700
701 fout << " p.Error = \"Parse error at token <\" + string(p.tokenVal[0:p.tokenLen]) + \">\"\n";
702 fout << " return false\n";
703 fout << " // print error message parse error\n";
704 fout << " }\n";
705 fout << " }\n";
706 fout << " }\n";
707 fout << "}\n";
708 fout << "\n";
709
710 // constructor
711 fout << "func NewParser( a ParserAction ) Parser {\n";
712 fout << " p := Parser{ act: a }\n";
713 fout << " p.loadScanner()\n";
714
715 for ( int i=0; i<=mcount; i++)
716 {
717 fout << " p.loadParser" + Chain(i) + "()\n";
718 }
719
720 fout << " p.loadProduction()\n";
721 fout << " return p\n";
722 fout << "}\n";
723
724 fout.close();
725
726 }
727
728
729
730