Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GPDL/SyntaxAnalyzer/GPDefSyntaxAnalyzerSyn.cs @ 9430

Last change on this file since 9430 was 9430, checked in by gkronber, 11 years ago

initial import of GPDL parser plugin

File size: 18.4 KB
Line 
1// GPDefSyntaxAnalyzerSyn.cs                                              HDO, 2006-08-28
2// -------------
3// Table-driven top-down syntax analyzer (G-code interpreter).
4// Generated by Coco-2 (PGT).
5//=====================================|========================================
6
7// --- call pragma mehts. and exec. sem. acts. after syntax errors? ---
8#define CONTPRAGMAACTS            // !!!must be defined for SG and PGT!!!
9#undef  CONTSEMACTS               // should not be defined
10
11using System;
12using System.Text;
13
14using Lex = GPDefSyntaxAnalyzerLex;
15using Sem = GPDefSyntaxAnalyzerSem;
16
17public class GPDefSyntaxAnalyzerSyn {
18                   
19  public static String MODULENAME = "GPDefSyntaxAnalyzerSyn";
20
21  // --- G-code instructions ---
22  public enum Instruction {
23    T, TA, TC, TCA, NT, NTA, ANY, ANYA, EPS, EPSA, JMP, RET
24  } // Instruction
25
26  private const int ROOTPC     =  207;
27  private const int LASTTERM   =   28;
28  private const int LASTPRAGMA =   29;
29
30
31  // --- other constants ---
32  private const int MINERRDIST   =   3;
33  private const int MAXSTACKLEN  = 100;
34  private const int EOFTOK       =   0;
35  private const int FIRSTNONTERM = LASTPRAGMA + 1;
36
37  public class NTData {
38    public int          startPC;
39    public bool         del;
40    public Sets.Set256  firstSet;
41    public NTData(int startPC, bool del, Sets.Set256 firstSet) {
42      this.startPC  = startPC;
43      this.del      = del;
44      this.firstSet = firstSet;
45    } // NTData
46  } // NTData
47 
48  private class GrammarTable {
49    public int[]  header = {
50      212, 28, 29, 41, 3, 0
51    };
52    public byte[] code = {
53         0,   1,   2,  28,   1,   1,  13,  10,   0,   1,  12,  14,   0,   0,
54         5,   5,   3,  24,   0,   2,  10,  16,   0,   0,  10,   5,   8,  34,
55         0,   3,  10,  26,   0,   0,   6,   5,   4,  44,   0,   4,  10,  36,
56         0,   1,   8,  56,   0,   0,   2,   2,  28,   5,   0,  19,  11,   0,
57         9,  10,  48,   0,   0,   4,  11,   0,   7,  11,   2,  28,   1,   0,
58        19,  11,   2,  28,   1,   0,  17,   5,   1,  83,   0,   2,   4,   5,
59         3,   0,  19,  11,   4,   6,   1,   1,  18, 102,   0,   4,   6,   2,
60        10,  92,   0,   8,   1,  11,   4,   7,   1,   5,   7, 116,   0,   2,
61        10, 108,   0,   8,   2,  11,   3,  28, 125,   0,   1,  11,   1,   3,
62       130,   0,  11,   1,  20, 140,   0,   4,   5,   2,   0,  21,  11,   1,
63        22, 150,   0,   4,   5,   3,   0,  23,  11,   1,  24, 160,   0,   4,
64         5,   4,   0,  25,  11,   4,   2,   5,  11,   2,  28,   1,   1,  11,
65       174,   0,   4,   9,   2,   0,  19,  11,   5,  10, 185,   0,   1,  10,
66       177,   0,   8,   3,  11,   2,  28,   1,   0,  14,   4,  11,   2,  11,
67         1,  15, 202,   0,  11,   0,  16,   0,  27,  11,   4,   0,   1,   0,
68         0,  11
69    };
70    public NTData[] nts = {
71      new NTData(   1, false, new Sets.Set256(0x0002)),
72      new NTData(  61, false, new Sets.Set256(0x0010)),
73      new NTData(  64, false, new Sets.Set256(0x0080)),
74      new NTData(  67, false, new Sets.Set256(0x0000, 0x1000)),
75      new NTData(  73, false, new Sets.Set256(0x0000, 0x1000)),
76      new NTData(  89, false, new Sets.Set256(0x0088, 0x1150)),
77      new NTData( 105, false, new Sets.Set256(0x0088, 0x1150)),
78      new NTData( 119, false, new Sets.Set256(0x0088, 0x1150)),
79      new NTData( 164, false, new Sets.Set256(0x0000, 0x1000)),
80      new NTData( 177, true , new Sets.Set256(0x0000, 0x1000)),
81      new NTData( 188, false, new Sets.Set256(0x0000, 0x1000)),
82      new NTData( 197, false, new Sets.Set256(0x8000, 0x0001))
83    };
84    public Sets.Set256[] epsSets = {
85      new Sets.Set256(0x0000, 0x02a8),
86      new Sets.Set256(0x0000, 0x02ac),
87      new Sets.Set256(0x0000, 0x0008)
88    };
89    public Sets.Set256[] anySets = {
90      new Sets.Set256(0x0000)
91    };
92    public String[] names = {
93      "end of file", "PROBLEM", "END", "EPS", "LOCAL", "NONTERMINALS",
94      "RULES", "SEM", "MAXIMIZE", "MINIMIZE", "TERMINALS", "CONSTRAINTS",
95      "INIT", "CODE", "IN", "SET", "RANGE", "=", "|", ".", "(", ")", "[",
96      "]", "{", "}", ">>", "..", "ident", "source", "GPDefSyntaxAnalyzer",
97      "SemDecl", "SemAction", "NonterminalDecl", "RuleDef", "SynExpr",
98      "SynTerm", "SynFact", "TerminalDecl", "ConstraintDef",
99      "ConstraintRule", "SetDefinition"
100    };
101  } // GrammarTable;
102
103  private static GrammarTable gt;
104
105  private static int   pc;             // G-code counter
106  private static int[] stk;            // stack of G-code return adresses
107  private static int   sp;             // stack pointer
108  private static bool  mustRead;       // next Lex.token to read
109  private static int   altRoot;        // root of alternative chain
110  private static bool  leaveOrEnter;   // leaveCnt > 0 OR enterCnt > 0
111  private static int   leaveCnt;       // nr. of sem. proc. to leave
112  private static int   enterCnt;       // nr. of sem. proc. to enter
113  private static int   errDist;        // current error distance
114  private static int[] stkAtErr;       // saved stack at error position
115  private static int[] newSP;          // new stack length
116  private static int[] newPC;          // pc after recovery
117
118
119  public static void GPDefSyntaxAnalyzerSynMethod(Utils.ModuleAction action, out String moduleName) {
120  //-----------------------------------|----------------------------------------
121    moduleName = MODULENAME;
122    switch (action) {
123      case Utils.ModuleAction.getModuleName:
124        return;
125      case Utils.ModuleAction.initModule:
126        Errors.InstallStopParsingMethod(StopParsing);
127        gt       = new GrammarTable();
128        stk      = new int[MAXSTACKLEN];
129        stkAtErr = new int[MAXSTACKLEN];
130        newSP    = new int[LASTTERM + 1];
131        newPC    = new int[LASTTERM + 1];
132        break;
133      case Utils.ModuleAction.resetModule:
134        break;
135      case Utils.ModuleAction.cleanupModule:
136        gt       = null;
137        stk      = null;
138        stkAtErr = null;
139        newSP    = null;
140        newPC    = null;
141        break;
142    } // switch
143  } // GPDefSyntaxAnalyzerSynMethod
144
145  private static void Push(int pc) {
146    if (sp < MAXSTACKLEN)
147      stk[sp++] = pc;
148    else
149      Errors.Restriction(MODULENAME, "Push", "parser stack overflow");
150  } // Push
151
152  private static int Pop() {
153    if (sp > 0)
154      return stk[--sp];
155    else {
156      Errors.CompilerError(MODULENAME, "Pop", "parser stack underflow");
157      return 0;
158    } // else
159  } // Pop
160
161  private static void GetNextToken() {
162    for (;;) {
163      Lex.GetToken(); // updates Lex.token
164      if (Lex.token <= LASTTERM)
165        return;
166  #if !CONTPRAGMAACTS
167      if (NumOfSynErrors() == 0)
168  #endif
169        Sem.pragmaMethods[Lex.token - LASTTERM - 1]();
170    } // for
171  } // GetNextToken
172
173  private static int AdrAt(int pc) {
174    return (gt.code[pc - 1] |
175           (gt.code[pc    ] << 8));
176  } // AdrAt
177
178  private static void AdjustPC(ref int pc) {
179    if (pc == 0)
180      return;
181    for (;;)
182      switch ((Instruction)gt.code[pc - 1]) {
183        case Instruction.T:
184        case Instruction.TA:
185        case Instruction.TC:
186        case Instruction.TCA:
187        case Instruction.NT:
188        case Instruction.NTA:
189        case Instruction.ANY:
190        case Instruction.ANYA:
191        case Instruction.EPS:
192        case Instruction.EPSA:
193          return;
194        case Instruction.JMP:
195          pc = AdrAt(pc + 1);
196          break;
197        case Instruction.RET:
198          pc = 0;
199          return;
200        default:
201          pc++; // syn. or sem. action
202          break;
203      } // switch
204  } // AdjustPC
205
206  private static void GetSymInstr(int pc,
207                        out int opcode, out int sy, out int nextPC, out int altPC) {
208    opcode = gt.code[pc - 1];
209    nextPC = 0; // dummy init
210    altPC  = 0; // dummy init
211    switch ((Instruction)opcode) {
212      case Instruction.T:
213      case Instruction.TA:
214      case Instruction.TC:
215      case Instruction.TCA:
216      case Instruction.ANYA:
217      case Instruction.EPS:
218      case Instruction.EPSA:
219        sy = gt.code[pc];
220        break;
221      case Instruction.NT:
222      case Instruction.NTA:
223        sy = gt.code[pc] + FIRSTNONTERM;
224        break;
225      default: // ANY, JMP, RET, SEM, SYN
226        sy = 0;
227        break;
228    } // switch
229    switch ((Instruction)opcode) {
230      case Instruction.T:
231      case Instruction.EPS:
232        nextPC = pc + 2;
233        altPC = 0;
234        break;
235      case Instruction.TC:
236      case Instruction.NT:
237        nextPC = pc + 3;
238        altPC = 0;
239        break;
240      case Instruction.TA:
241      case Instruction.ANYA:
242      case Instruction.EPSA:
243        nextPC = pc + 4;
244        altPC = AdrAt(pc + 2);
245        break;
246      case Instruction.TCA:
247      case Instruction.NTA:
248        nextPC = pc + 5;
249        altPC = AdrAt(pc + 2);
250        break;
251      case Instruction.ANY:
252        nextPC = pc + 1;
253        altPC = 0;
254        break;
255    } // switch
256    AdjustPC(ref nextPC);
257    AdjustPC(ref altPC);
258  } // GetSymInstr
259
260  private static void Fill(int pc, int sp) {
261    int opcode, sy, nextPC, altPC, i;
262    AdjustPC(ref pc);
263    while (pc > 0) {
264      GetSymInstr(pc, out opcode, out sy, out nextPC, out altPC);
265      switch ((Instruction)opcode) {
266        case Instruction.T:
267        case Instruction.TA:
268        case Instruction.TC:
269        case Instruction.TCA:
270          newPC[sy] = pc;
271          newSP[sy] = sp;
272          break;
273        case Instruction.NT:
274        case Instruction.NTA:
275          for (i = 0; i <= LASTTERM; i++)
276            if (Sets.member((ushort)i, gt.nts[sy - FIRSTNONTERM].firstSet)) {
277              newPC[i] = pc;
278              newSP[i] = sp;
279            }
280          if (gt.nts[sy - FIRSTNONTERM].del)
281            Fill(nextPC, sp);
282          break;
283        case Instruction.EPS:
284        case Instruction.EPSA:
285          Fill(nextPC, sp);
286          break;
287      } // switch
288      pc = altPC;
289    } // while
290  } // Fill
291
292  private static void FillSucc(int pc, int sp) {
293    int opcode, sy, nextPC, altPC;
294    AdjustPC(ref pc);
295    while (pc > 0) {
296      GetSymInstr(pc, out opcode, out sy, out nextPC, out altPC);
297      if (nextPC > 0)
298        Fill(nextPC, sp);
299      pc = altPC;
300    } // while
301  } // FillSucc
302
303  private static void Triple(int altRoot) {
304    for (int i = 0; i <= LASTTERM; i++) { // clear triple list
305      newPC[i] = 0;
306      newSP[i] = 0;
307    } // for
308    for (int i = 1; i <= sp; i++) {       // successors of stacked nt's
309      FillSucc(stk[i - 1], i - 1);
310      Fill(stk[i - 1], i - 1);
311    } // for
312    FillSucc(altRoot, sp);                // successors of alt. chain
313    Fill(altRoot, sp);                    // current alt. chain
314  } // Triple
315
316  private static void HandleSynErr(ref int pc, ref int altRoot) {
317    int     opcode, sy, nextPC, altPC, adjPC, nwSP, eq;
318    bool    nameInMsg;
319    String  name;
320    StringBuilder msg = new StringBuilder();
321    leaveOrEnter = false;
322    if (errDist >= MINERRDIST) { // --- primary error
323      nameInMsg = false;
324      adjPC = altRoot;
325      AdjustPC(ref adjPC);
326      while (adjPC > 0) {
327        GetSymInstr(adjPC, out opcode, out sy, out nextPC, out altPC);
328        if ( (Instruction)opcode >= Instruction.T  &&
329             (Instruction)opcode <= Instruction.NTA  ) {
330          if ( gt.names[sy].IndexOf(' ') >= 0 ||
331               !Char.IsLetter(gt.names[sy][0]) )
332            name = "\"" + gt.names[sy] + "\"";
333          else
334            name = gt.names[sy];
335          if (name.IndexOf('{') > -1) // prevent formatting problems in Errors.SynError
336            name = name.Replace("{", "{{");
337          if (name.IndexOf('}') > -1) // prevent formatting problems in Errors.SynError
338            name = name.Replace("}", "}}");
339          if (msg.Length + name.Length + 2 > 80) {
340            msg.Append(" ...");
341            break;
342          } // if
343          if (!nameInMsg) {
344            nameInMsg = true;
345            msg.Append("expected: " + name);
346          } else {
347            msg.Append(", ");
348            msg.Append(name);
349          } // else
350        } // if
351        adjPC = altPC;
352      } // while
353      if (!nameInMsg)
354        msg.Append("syntax error");
355      Errors.SynError(Lex.tokenLine, Lex.tokenCol, msg.ToString(), "");
356      Triple(altRoot);
357      while (newPC[Lex.token] == 0) {
358        GetNextToken();      // may result in a call to StopParsing
359        if (leaveOrEnter)
360          return;
361      } // while
362      nwSP = newSP[Lex.token];
363      leaveCnt = sp - nwSP;
364      enterCnt = 0;
365      Array.Copy(stk, stkAtErr, stk.Length); // save stack
366    } else {                 // --- spurios error
367      if (errDist == 0) {    // no token used since last error
368        GetNextToken();      // may result in a call to StopParsing
369        if (leaveOrEnter)
370          return;
371      } // if
372      while (newPC[Lex.token] == 0) {
373        GetNextToken();      // may result in a call to StopParsing
374        if (leaveOrEnter)
375          return;
376      } // while
377      nwSP = newSP[Lex.token];
378      eq = 2;                // compare stkAtErr and stk
379      while (eq <= sp && eq <= nwSP && stkAtErr[eq - 1] == stk[eq - 1])
380        eq++;
381      eq--;                  // stacks are equal up to index eq
382      leaveCnt = sp - eq;
383      if (nwSP < eq) {
384        leaveCnt = sp - nwSP;
385        enterCnt = 0;
386      } else if (nwSP > eq)
387        enterCnt = nwSP - eq;
388      else // nwSP == eq
389        enterCnt = 0;
390      Array.Copy(stkAtErr, stk, stk.Length); // restore stack
391    } // else
392    leaveOrEnter = (leaveCnt + enterCnt) > 0;
393    sp = nwSP;
394    pc = newPC[Lex.token];
395    altRoot = pc;
396    errDist = 0;
397  } // HandleSynErr
398
399  public static int Interpret() {
400  //-----------------------------------|----------------------------------------
401    int actionNr, opcode, currPC;
402    for (;;) {
403      opcode = gt.code[pc - 1];
404      if ( !leaveOrEnter && mustRead &&
405           (Instruction)opcode <= Instruction.EPSA ) {
406        GetNextToken();
407        mustRead = false;
408        errDist++;
409        altRoot = pc;
410      } // if
411      if (leaveOrEnter) {
412        if (leaveCnt > 0) {
413          leaveCnt--;
414          actionNr = 0;
415        } else { // enterCnt > 0
416          enterCnt--;
417          actionNr = gt.code[stkAtErr[sp - enterCnt - 1] - 2];
418        } // else
419        leaveOrEnter = (leaveCnt + enterCnt) > 0;
420        return actionNr;
421      } // if
422      pc++;
423      switch ((Instruction)opcode) {
424        case Instruction.T:
425          if (Lex.token == gt.code[pc - 1])
426            if (Lex.token != EOFTOK) {
427              pc++;
428              mustRead = true;
429            } else {
430              return 0;
431            } // else
432          else
433            HandleSynErr(ref pc, ref altRoot);
434          break;
435        case Instruction.TA:
436          if (Lex.token == gt.code[pc - 1]) {
437            pc += 3;
438            mustRead = true;
439          } else
440            pc = AdrAt(pc + 1); // try alternative
441          break;
442        case Instruction.TC:
443          if (Lex.token == gt.code[pc - 1]) {
444            pc += 2;
445            mustRead = true;
446            actionNr = gt.code[pc - 2];
447            return actionNr;
448          } else
449            HandleSynErr(ref pc, ref altRoot);
450          break;
451        case Instruction.TCA:
452          if (Lex.token == gt.code[pc - 1]) {
453            pc += 4;
454            mustRead = true;
455            actionNr = gt.code[pc - 2];
456            return actionNr;
457          } else
458            pc = AdrAt(pc + 1); // try alternative
459          break;
460        case Instruction.NT:
461          currPC = gt.code[pc - 1];
462          if ( gt.nts[currPC].del ||
463               Sets.member((ushort)Lex.token, gt.nts[currPC].firstSet) ) {
464            pc++;
465            actionNr = gt.code[pc - 1];
466            Push(pc + 1);
467            pc = gt.nts[currPC].startPC;
468            altRoot = pc;
469            return actionNr;
470          } else
471            HandleSynErr(ref pc, ref altRoot);
472          break;
473        case Instruction.NTA:
474          currPC = gt.code[pc - 1];
475          if (Sets.member((ushort)Lex.token, gt.nts[currPC].firstSet)) {
476            pc += 3;
477            actionNr = gt.code[pc - 1];
478            Push(pc + 1);
479            pc = gt.nts[currPC].startPC;
480            altRoot = pc;
481            return actionNr;
482          } else
483            pc = AdrAt(pc + 1);
484          break;
485        case Instruction.ANY:
486          mustRead = true;
487          break;
488        case Instruction.ANYA:
489          currPC = gt.code[pc - 1];
490          if (Sets.member((ushort)Lex.token, gt.anySets[currPC - 1])) {
491            pc += 3;
492            mustRead = true;
493          } else
494            pc = AdrAt(pc + 1);
495          break;
496        case Instruction.EPS:
497          currPC = gt.code[pc - 1];
498          if (Sets.member((ushort)Lex.token, gt.epsSets[currPC - 1]))
499            pc++;
500          else
501            HandleSynErr(ref pc, ref altRoot);
502          break;
503        case Instruction.EPSA:
504          currPC = gt.code[pc - 1];
505          if (Sets.member((ushort)Lex.token, gt.epsSets[currPC - 1]))
506            pc += 3;
507          else
508            pc = AdrAt(pc + 1);
509          break;
510        case Instruction.JMP:
511          pc = AdrAt(pc);
512          break;
513        case Instruction.RET:
514          pc = Pop();
515          altRoot = pc;
516          return 0;
517        default:
518          if (opcode <= 128) {
519  #if !CONTSEMACTS
520          if (Errors.NumOfSynErrors() == 0)
521  #endif
522            return opcode - 12;
523          } else // opcode > 128
524            return opcode - 128;
525          break;
526      } // switch
527    } // for
528  } // Interpret
529
530
531  public static bool Parse() {
532  //-----------------------------------|----------------------------------------
533    Lex.InitLex();
534    sp           = 0;
535    pc           = ROOTPC;
536    altRoot      = pc;
537    mustRead     = true;
538    errDist      = MINERRDIST + 1;
539    leaveOrEnter = false;
540    leaveCnt     = 0;
541    enterCnt     = 0;
542    Sem.StartSem();
543    return Errors.NumOfSynErrors() == 0;
544  } // Parse
545
546
547  public static void StopParsing() {
548  //-----------------------------------|----------------------------------------
549    leaveCnt     = sp + 1;
550    enterCnt     = 0;
551    leaveOrEnter = true;
552  } // StopParsing
553
554} // GPDefSyntaxAnalyzerSyn
555 
556// End of GPDefSyntaxAnalyzerSyn.cs
557//=====================================|========================================
Note: See TracBrowser for help on using the repository browser.