Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GPDL/HeuristicLab.Problems.GPDL/3.4/Parser.cs @ 10065

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

#2026 added shell script to generate parser and scanner on linux also adapted pre- and post-build events

File size: 10.0 KB
Line 
1using System.Text;
2using System.Collections.Generic;
3using System.Linq;
4using IEnumerableConstraintNode = System.Collections.Generic.IEnumerable<ConstraintNode>;
5
6
7
8using System;
9
10namespace HeuristicLab.Problems.GPDL {
11
12
13
14public class Parser {
15  public const int _EOF = 0;
16  public const int _ident = 1;
17  public const int maxT = 23;
18
19  const bool T = true;
20  const bool x = false;
21  const int minErrDist = 2;
22 
23  public Scanner scanner;
24  public Errors  errors;
25
26  public Token t;    // last recognized token
27  public Token la;   // lookahead token
28  int errDist = minErrDist;
29
30public GPDefNode AbstractSyntaxTree { get; private set; }
31
32
33
34  public Parser(Scanner scanner) {
35    this.scanner = scanner;
36    errors = new Errors();
37  }
38
39  void SynErr (int n) {
40    if (errDist >= minErrDist) errors.SynErr(la.line, la.col, n);
41    errDist = 0;
42  }
43
44  public void SemErr (string msg) {
45    if (errDist >= minErrDist) errors.SemErr(t.line, t.col, msg);
46    errDist = 0;
47  }
48 
49  void Get () {
50    for (;;) {
51      t = la;
52      la = scanner.Scan();
53      if (la.kind <= maxT) { ++errDist; break; }
54
55      la = t;
56    }
57  }
58 
59  void Expect (int n) {
60    if (la.kind==n) Get(); else { SynErr(n); }
61  }
62 
63  bool StartOf (int s) {
64    return set[s, la.kind];
65  }
66 
67  void ExpectWeak (int n, int follow) {
68    if (la.kind == n) Get();
69    else {
70      SynErr(n);
71      while (!StartOf(follow)) Get();
72    }
73  }
74
75
76  bool WeakSeparator(int n, int syFol, int repFol) {
77    int kind = la.kind;
78    if (kind == n) {Get(); return true;}
79    else if (StartOf(repFol)) {return false;}
80    else {
81      SynErr(n);
82      while (!(set[syFol, kind] || set[repFol, kind] || set[0, kind])) {
83        Get();
84        kind = la.kind;
85      }
86      return StartOf(syFol);
87    }
88  }
89
90 
91  void SourceCode(out string src) {
92    src = "";
93    Expect(2);
94    int beg = la.pos;
95    while (StartOf(1)) {
96      Get();
97    }
98    int end = la.pos;
99    Expect(3);
100    if(end>beg) src = scanner.buffer.GetString(beg, end);
101  }
102
103  void GPDef() {
104    RuleNode ruleNode = null;
105    GPDefNode gpDef = new GPDefNode();
106    NonTerminalNode ntNode = null;
107    FitnessFunctionNode fitnessFunNode = null;
108    TerminalNode tNode = null;
109    string src = "";
110   
111    Expect(4);
112    Expect(1);
113    gpDef.Name = t.val;
114    if (la.kind == 5) {
115      Get();
116      SourceCode(out src);
117      gpDef.ClassCodeNode = new CodeNode{SrcCode = src};
118    }
119    if (la.kind == 6) {
120      Get();
121      SourceCode(out src);
122      gpDef.InitCodeNode = new CodeNode{SrcCode = src};
123    }
124    Expect(7);
125    while (la.kind == 1) {
126      NonterminalDecl(out ntNode);
127      if(gpDef.IsSymbolDefined(ntNode)) {
128       SemErr("Duplicate non-terminal symbol: " + ntNode.Ident);
129      } else {
130       gpDef.NonTerminals.Add(ntNode);
131      }
132     
133    }
134    if(!gpDef.NonTerminals.Any())
135     SemErr("No non-terminal symbols defined.");
136   
137    Expect(8);
138    while (la.kind == 1) {
139      TerminalDecl(out tNode);
140      if(gpDef.IsSymbolDefined(tNode)) {
141       SemErr("Duplicate terminal symbol: " + tNode.Ident);
142      } else {
143       gpDef.Terminals.Add(tNode);
144      }
145     
146    }
147    if(!gpDef.Terminals.Any())
148     SemErr("No terminal symbols defined.");
149   
150    Expect(9);
151    while (la.kind == 1) {
152      RuleDef(out ruleNode);
153      if(!gpDef.IsNonTerminalDefined(ruleNode.NtSymbol)) {
154       SemErr("Non-terminal symbol " + ruleNode.NtSymbol + " is not defined in the NONTERMINALS section.");
155      } else if(gpDef.IsRuleDefined(ruleNode)) {
156       SemErr("Duplicate rule definition for non-terminal symbol " + ruleNode.NtSymbol);
157      } else {
158       gpDef.Rules.Add(ruleNode);
159      }
160     
161    }
162    var undefinedNT = gpDef.UndefinedNonTerminals();
163    if(!string.IsNullOrEmpty(undefinedNT)) {
164     SemErr("Rules missing in the RULES section for: " + undefinedNT);
165    }
166   
167    fitnessFunNode = new FitnessFunctionNode();
168    gpDef.FitnessFunctionNode = fitnessFunNode;
169   
170    if (la.kind == 10) {
171      Get();
172      fitnessFunNode.Maximization = true;
173    } else if (la.kind == 11) {
174      Get();
175      fitnessFunNode.Maximization = false;
176    } else SynErr(24);
177    SourceCode(out src);
178    fitnessFunNode.SrcCode = src;
179    if(errors.count > 0) throw new FatalError("Syntactic or semantic errors found.");
180    Expect(12);
181    Expect(1);
182    AbstractSyntaxTree = gpDef;
183   
184    Expect(13);
185  }
186
187  void NonterminalDecl(out NonTerminalNode ntNode) {
188    string identStr = ""; ntNode = null; string src = "";
189    Expect(1);
190    identStr = t.val;
191    if (la.kind == 2) {
192      SourceCode(out src);
193    }
194    var myNtNode = new NonTerminalNode();
195    ntNode = myNtNode;
196    myNtNode.Ident = identStr;
197    myNtNode.FormalParameters = src;
198   
199    Expect(13);
200  }
201
202  void TerminalDecl(out TerminalNode tNode) {
203    string identStr = "";
204    tNode = null;
205    TerminalNode myTNode = null;
206    IEnumerableConstraintNode constraints = new List<ConstraintNode>();
207    string src = "";
208   
209    Expect(1);
210    identStr = t.val;
211    if (la.kind == 2) {
212      SourceCode(out src);
213    }
214    myTNode = new TerminalNode();
215    tNode = myTNode;
216    myTNode.Ident = identStr;
217    myTNode.FormalParameters = src;
218    myTNode.FieldDefinitions = Util.ExtractFormalParameters(src);
219   
220    if (la.kind == 15) {
221      Get();
222      ConstraintDef(out constraints);
223    }
224    myTNode.Constraints = constraints;
225    Expect(13);
226  }
227
228  void RuleDef(out RuleNode rule) {
229    RuleExprNode expr = null;
230    string identStr = null;
231    RuleNode myRule = null;
232    rule = null;
233    string src = "";
234   
235    Expect(1);
236    identStr = t.val;
237    if (la.kind == 2) {
238      SourceCode(out src);
239    }
240    Expect(20);
241    myRule = new RuleNode();
242    rule = myRule;
243    myRule.NtSymbol = identStr;
244   
245    if (la.kind == 21) {
246      Get();
247      SourceCode(out src);
248      myRule.LocalCode = src;
249     
250    }
251    SynExpr(out expr);
252    Expect(13);
253    myRule.RuleExpr = expr;
254   
255  }
256
257  void SemAction(out RuleActionNode action) {
258    RuleActionNode myAction = null; action = null; string src = "";
259    Expect(14);
260    SourceCode(out src);
261    myAction = new RuleActionNode();
262    myAction.SrcCode = src;
263    action = myAction;
264   
265  }
266
267  void ConstraintDef(out IEnumerableConstraintNode constraints) {
268    List<ConstraintNode> constraintsList = new List<ConstraintNode>();
269    ConstraintNode n = null;
270    constraints = null;
271   
272    while (la.kind == 1) {
273      ConstraintRule(out n);
274      constraintsList.Add(n);
275    }
276    constraints = constraintsList;
277  }
278
279  void ConstraintRule(out ConstraintNode constraint) {
280    constraint = null;
281   
282    Expect(1);
283    constraint = new ConstraintNode(t.val);
284    Expect(16);
285    SetDefinition(constraint);
286  }
287
288  void SetDefinition(ConstraintNode constraint) {
289    string src = "";
290    if (la.kind == 17) {
291      Get();
292      constraint.Type = ConstraintNodeType.Set;
293      SourceCode(out src);
294      constraint.SetExpression = src;
295    } else if (la.kind == 18) {
296      Get();
297      constraint.Type = ConstraintNodeType.Range;
298      SourceCode(out src);
299      constraint.RangeMinExpression = src;
300      Expect(19);
301      SourceCode(out src);
302      constraint.RangeMaxExpression = src;
303    } else SynErr(25);
304  }
305
306  void SynExpr(out RuleExprNode expr ) {
307    expr = null;
308    AlternativesNode alt = null;
309   
310    SynTerm(out expr);
311    alt = new AlternativesNode();
312    alt.Add(expr);
313   
314    while (la.kind == 22) {
315      Get();
316      SynTerm(out expr);
317      alt.Add(expr); expr = alt;
318    }
319  }
320
321  void SynTerm(out RuleExprNode expr) {
322    SequenceNode seq = null; expr = null;
323    SynFact(out expr);
324    seq = new SequenceNode();
325    seq.Add(expr);
326   
327    while (la.kind == 1 || la.kind == 14) {
328      SynFact(out expr);
329      seq.Add(expr); expr = seq;
330    }
331  }
332
333  void SynFact(out RuleExprNode expr) {
334    string identStr = "";
335    RuleActionNode action = null;
336    expr = null;
337    string src = "";
338   
339    if (la.kind == 1) {
340      Get();
341      identStr = t.val;
342      if (la.kind == 2) {
343        SourceCode(out src);
344      }
345      var callNode = new CallSymbolNode{Ident = identStr};
346      callNode.ActualParameter = src;
347      expr = callNode;
348     
349    } else if (la.kind == 14) {
350      SemAction(out action);
351      expr = action;
352    } else SynErr(26);
353  }
354
355
356
357  public void Parse() {
358    la = new Token();
359    la.val = "";   
360    Get();
361    GPDef();
362    Expect(0);
363
364  }
365 
366  static readonly bool[,] set = {
367    {T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
368    {x,T,T,x, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, x}
369
370  };
371} // end Parser
372
373
374public class Errors {
375  public int count = 0;                                    // number of errors detected
376  public System.IO.TextWriter errorStream = Console.Out;   // error messages go to this stream
377  public string errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text
378
379  public virtual void SynErr (int line, int col, int n) {
380    string s;
381    switch (n) {
382      case 0: s = "EOF expected"; break;
383      case 1: s = "ident expected"; break;
384      case 2: s = "\"<<\" expected"; break;
385      case 3: s = "\">>\" expected"; break;
386      case 4: s = "\"PROBLEM\" expected"; break;
387      case 5: s = "\"CODE\" expected"; break;
388      case 6: s = "\"INIT\" expected"; break;
389      case 7: s = "\"NONTERMINALS\" expected"; break;
390      case 8: s = "\"TERMINALS\" expected"; break;
391      case 9: s = "\"RULES\" expected"; break;
392      case 10: s = "\"MAXIMIZE\" expected"; break;
393      case 11: s = "\"MINIMIZE\" expected"; break;
394      case 12: s = "\"END\" expected"; break;
395      case 13: s = "\".\" expected"; break;
396      case 14: s = "\"SEM\" expected"; break;
397      case 15: s = "\"CONSTRAINTS\" expected"; break;
398      case 16: s = "\"IN\" expected"; break;
399      case 17: s = "\"SET\" expected"; break;
400      case 18: s = "\"RANGE\" expected"; break;
401      case 19: s = "\"..\" expected"; break;
402      case 20: s = "\"=\" expected"; break;
403      case 21: s = "\"LOCAL\" expected"; break;
404      case 22: s = "\"|\" expected"; break;
405      case 23: s = "??? expected"; break;
406      case 24: s = "invalid GPDef"; break;
407      case 25: s = "invalid SetDefinition"; break;
408      case 26: s = "invalid SynFact"; break;
409
410      default: s = "error " + n; break;
411    }
412    errorStream.WriteLine(errMsgFormat, line, col, s);
413    count++;
414  }
415
416  public virtual void SemErr (int line, int col, string s) {
417    errorStream.WriteLine(errMsgFormat, line, col, s);
418    count++;
419  }
420 
421  public virtual void SemErr (string s) {
422    errorStream.WriteLine(s);
423    count++;
424  }
425 
426  public virtual void Warning (int line, int col, string s) {
427    errorStream.WriteLine(errMsgFormat, line, col, s);
428  }
429 
430  public virtual void Warning(string s) {
431    errorStream.WriteLine(s);
432  }
433} // Errors
434
435
436public class FatalError: Exception {
437  public FatalError(string m): base(m) {}
438}
439}
Note: See TracBrowser for help on using the repository browser.