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