Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2026 added lawn mower problem. create a OSGA for solving the compiled problem directly

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