Free cookie consent management tool by TermsFeed Policy Generator

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