]> gerrit.simantics Code Review - simantics/platform.git/blob
9c1a61535531e97b55acf36d0d6830e3b0ec6313
[simantics/platform.git] /
1 package org.simantics.scl.compiler.internal.parsing.parser;
2
3 import java.io.Reader;
4 import java.util.ArrayList;
5 import java.util.Arrays;
6 import java.util.List;
7
8 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
9 import org.simantics.scl.compiler.common.precedence.Associativity;
10 import org.simantics.scl.compiler.common.precedence.Precedence;
11 import org.simantics.scl.compiler.compilation.CompilationContext;
12 import org.simantics.scl.compiler.constants.CharacterConstant;
13 import org.simantics.scl.compiler.constants.StringConstant;
14 import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstAtom;
15 import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstBinds;
16 import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstConjunction;
17 import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstEquals;
18 import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstQuery;
19 import org.simantics.scl.compiler.elaboration.equation.EqBasic;
20 import org.simantics.scl.compiler.elaboration.equation.EqGuard;
21 import org.simantics.scl.compiler.elaboration.equation.Equation;
22 import org.simantics.scl.compiler.elaboration.expressions.Case;
23 import org.simantics.scl.compiler.elaboration.expressions.EApply;
24 import org.simantics.scl.compiler.elaboration.expressions.EAsPattern;
25 import org.simantics.scl.compiler.elaboration.expressions.EBinary;
26 import org.simantics.scl.compiler.elaboration.expressions.EBinaryRightSide;
27 import org.simantics.scl.compiler.elaboration.expressions.EBlock;
28 import org.simantics.scl.compiler.elaboration.expressions.EConstant;
29 import org.simantics.scl.compiler.elaboration.expressions.EEnforce;
30 import org.simantics.scl.compiler.elaboration.expressions.EEquations;
31 import org.simantics.scl.compiler.elaboration.expressions.EFieldAccess;
32 import org.simantics.scl.compiler.elaboration.expressions.EIf;
33 import org.simantics.scl.compiler.elaboration.expressions.EIntegerLiteral;
34 import org.simantics.scl.compiler.elaboration.expressions.ELambda;
35 import org.simantics.scl.compiler.elaboration.expressions.EListComprehension;
36 import org.simantics.scl.compiler.elaboration.expressions.EListLiteral;
37 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
38 import org.simantics.scl.compiler.elaboration.expressions.EMatch;
39 import org.simantics.scl.compiler.elaboration.expressions.EPreCHRSelect;
40 import org.simantics.scl.compiler.elaboration.expressions.ERange;
41 import org.simantics.scl.compiler.elaboration.expressions.ERealLiteral;
42 import org.simantics.scl.compiler.elaboration.expressions.ERecord;
43 import org.simantics.scl.compiler.elaboration.expressions.ESelect;
44 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
45 import org.simantics.scl.compiler.elaboration.expressions.EStringLiteral;
46 import org.simantics.scl.compiler.elaboration.expressions.ETransformation;
47 import org.simantics.scl.compiler.elaboration.expressions.ETypeAnnotation;
48 import org.simantics.scl.compiler.elaboration.expressions.EVar;
49 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
50 import org.simantics.scl.compiler.elaboration.expressions.EViewPattern;
51 import org.simantics.scl.compiler.elaboration.expressions.Expression;
52 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpression;
53 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpressionGroup;
54 import org.simantics.scl.compiler.elaboration.expressions.Variable;
55 import org.simantics.scl.compiler.elaboration.expressions.accessor.ExpressionAccessor;
56 import org.simantics.scl.compiler.elaboration.expressions.accessor.FieldAccessor;
57 import org.simantics.scl.compiler.elaboration.expressions.accessor.IdAccessor;
58 import org.simantics.scl.compiler.elaboration.expressions.accessor.StringAccessor;
59 import org.simantics.scl.compiler.elaboration.expressions.block.BindStatement;
60 import org.simantics.scl.compiler.elaboration.expressions.block.BlockType;
61 import org.simantics.scl.compiler.elaboration.expressions.block.CHRStatement;
62 import org.simantics.scl.compiler.elaboration.expressions.block.ConstraintStatement;
63 import org.simantics.scl.compiler.elaboration.expressions.block.GuardStatement;
64 import org.simantics.scl.compiler.elaboration.expressions.block.IncludeStatement;
65 import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement;
66 import org.simantics.scl.compiler.elaboration.expressions.block.RuleStatement;
67 import org.simantics.scl.compiler.elaboration.expressions.block.Statement;
68 import org.simantics.scl.compiler.elaboration.expressions.list.ListAssignment;
69 import org.simantics.scl.compiler.elaboration.expressions.list.ListGenerator;
70 import org.simantics.scl.compiler.elaboration.expressions.list.ListGuard;
71 import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifier;
72 import org.simantics.scl.compiler.elaboration.expressions.list.ListSeq;
73 import org.simantics.scl.compiler.elaboration.expressions.list.ListThen;
74 import org.simantics.scl.compiler.elaboration.expressions.records.FieldAssignment;
75 import org.simantics.scl.compiler.elaboration.java.Builtins;
76 import org.simantics.scl.compiler.elaboration.query.QAlternative;
77 import org.simantics.scl.compiler.elaboration.query.QConjunction;
78 import org.simantics.scl.compiler.elaboration.query.QDisjunction;
79 import org.simantics.scl.compiler.elaboration.query.QNegation;
80 import org.simantics.scl.compiler.elaboration.query.Query;
81 import org.simantics.scl.compiler.elaboration.query.pre.QPreBinds;
82 import org.simantics.scl.compiler.elaboration.query.pre.QPreEquals;
83 import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard;
84 import org.simantics.scl.compiler.errors.Locations;
85 import org.simantics.scl.compiler.internal.header.ModuleHeader;
86 import org.simantics.scl.compiler.internal.parsing.Symbol;
87 import org.simantics.scl.compiler.internal.parsing.Token;
88 import org.simantics.scl.compiler.internal.parsing.declarations.ConstructorAst;
89 import org.simantics.scl.compiler.internal.parsing.declarations.DAnnotationAst;
90 import org.simantics.scl.compiler.internal.parsing.declarations.DClassAst;
91 import org.simantics.scl.compiler.internal.parsing.declarations.DDataAst;
92 import org.simantics.scl.compiler.internal.parsing.declarations.DDerivingInstanceAst;
93 import org.simantics.scl.compiler.internal.parsing.declarations.DDocumentationAst;
94 import org.simantics.scl.compiler.internal.parsing.declarations.DEffectAst;
95 import org.simantics.scl.compiler.internal.parsing.declarations.DFixityAst;
96 import org.simantics.scl.compiler.internal.parsing.declarations.DImportJavaAst;
97 import org.simantics.scl.compiler.internal.parsing.declarations.DInstanceAst;
98 import org.simantics.scl.compiler.internal.parsing.declarations.DMappingRelationAst;
99 import org.simantics.scl.compiler.internal.parsing.declarations.DRelationAst;
100 import org.simantics.scl.compiler.internal.parsing.declarations.DRuleAst;
101 import org.simantics.scl.compiler.internal.parsing.declarations.DRulesetAst;
102 import org.simantics.scl.compiler.internal.parsing.declarations.DTypeAst;
103 import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst;
104 import org.simantics.scl.compiler.internal.parsing.declarations.DValueTypeAst;
105 import org.simantics.scl.compiler.internal.parsing.declarations.DeclarationAst;
106 import org.simantics.scl.compiler.internal.parsing.declarations.FieldDescription;
107 import org.simantics.scl.compiler.internal.parsing.declarations.FundepAst;
108 import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
109 import org.simantics.scl.compiler.internal.parsing.types.TApplyAst;
110 import org.simantics.scl.compiler.internal.parsing.types.TEffectAst;
111 import org.simantics.scl.compiler.internal.parsing.types.TForAllAst;
112 import org.simantics.scl.compiler.internal.parsing.types.TFunctionAst;
113 import org.simantics.scl.compiler.internal.parsing.types.TListAst;
114 import org.simantics.scl.compiler.internal.parsing.types.TPredAst;
115 import org.simantics.scl.compiler.internal.parsing.types.TTupleAst;
116 import org.simantics.scl.compiler.internal.parsing.types.TVarAst;
117 import org.simantics.scl.compiler.internal.parsing.types.TypeAst;
118 import org.simantics.scl.compiler.module.ImportDeclaration;
119 import org.simantics.scl.compiler.types.Types;
120
121
122 public class SCLParserImpl extends SCLParser {
123
124     private final SCLPostLexer lexer;
125     private SCLParserOptions options;
126     private CompilationContext context;
127
128     public SCLParserImpl(Reader reader) {
129         this.lexer = new SCLPostLexer(reader);
130     }
131     
132     public SCLPostLexer getLexer() {
133         return lexer;
134     }
135     
136     public void setCompilationContext(CompilationContext context) {
137         this.context = context;
138         lexer.setCompilationContext(context);
139     }
140     
141     public void setParserOptions(SCLParserOptions options) {
142         this.options = options;
143         lexer.setParserOptions(options);
144     }
145     
146     public boolean isEmpty() throws Exception {
147         return lexer.peekToken().id == SCLTerminals.EOF;
148     }
149
150     @Override
151     protected Token nextToken() {
152         try {
153             Token token = lexer.nextToken();
154             /*System.out.println("TOKEN " + token.text + " (" + TERMINAL_NAMES[token.id] + ")" +
155                     " [" 
156                     + Locations.beginOf(token.location) + ".." 
157                     + Locations.endOf(token.location) + "]");*/
158             return token;
159         } catch(Exception e) {
160             if(e instanceof RuntimeException)
161                 throw (RuntimeException)e;
162             else
163                 throw new RuntimeException(e);
164         }
165     }
166
167     @Override
168     protected Object reduceDeclarations() {
169         ArrayList<DeclarationAst> declarations = new ArrayList<DeclarationAst>(length()/2);
170         for(int i=1;i<length();i+=2)
171             declarations.add((DeclarationAst)get(i));
172         return declarations;
173     }
174
175     @Override
176     protected Object reduceModule() {
177         ArrayList<DeclarationAst> declarations = new ArrayList<DeclarationAst>(length()/2+1);
178         for(int i=0;i<length();i+=2) {
179             DeclarationAst declaration = (DeclarationAst)get(i);
180             if(declaration == null)
181                 continue;
182             declarations.add(declaration);
183         }
184         return declarations;
185     }
186     
187     @Override
188     protected Object reduceModuleHeader() {
189         FieldAssignment[] fields = new FieldAssignment[length()/2-1];
190         for(int i=0;i<fields.length;++i)
191             fields[i] = (FieldAssignment)get(2+i*2);
192         context.header = ModuleHeader.process(context.errorLog, fields);
193         return null;
194     }
195
196     @Override
197     protected Object reduceLocalTypeAnnotation() {
198         if(length() == 1)
199             return get(0);
200         return new ETypeAnnotation((Expression)get(0), (TypeAst)get(2));
201     }
202
203     @Override
204     protected Object reduceTypeAnnotation() {
205         EVar[] names = new EVar[length()/2];
206         for(int i=0;i<names.length;++i)
207             names[i] = (EVar)get(i*2);
208         return new DValueTypeAst(
209                 names,
210                 (TypeAst)get(length()-1)
211                 );
212     }
213
214     @Override
215     protected Object reduceValueDefinition() {
216         Expression rhs = (Expression)get(1);
217         return new DValueAst((Expression)get(0), rhs);
218     }
219
220     @Override
221     protected Object reduceDataDefinition() {
222         int i=2;
223         ArrayList<String> parameters = new ArrayList<String>();
224         while(i < length()) {
225             Token token = (Token)get(i++);
226             if(token.id != SCLTerminals.ID)
227                 break;
228             parameters.add(token.text);
229         }
230         ArrayList<ConstructorAst> constructors = new ArrayList<ConstructorAst>(); 
231         for(;i < length();i+=2)
232             constructors.add((ConstructorAst)get(i));
233         return new DDataAst(
234                 ((Token)get(1)).text,
235                 parameters.toArray(new String[parameters.size()]),
236                 constructors.toArray(new ConstructorAst[constructors.size()]),
237                 new String[0]
238                 );
239     }
240
241     @Override
242     protected Object reduceTypeDefinition() {
243         int i=2;
244         ArrayList<String> parameters = new ArrayList<String>();
245         while(true) {
246             Token token = (Token)get(i++);
247             if(token.id != SCLTerminals.ID)
248                 break;
249             parameters.add(token.text);
250         }
251         return new DTypeAst(
252                 ((Token)get(1)).text,
253                 parameters.toArray(new String[parameters.size()]),
254                 (TypeAst)get(i)
255                 );
256     }
257
258     @SuppressWarnings("unchecked")
259     @Override
260     protected Object reduceClassDefinition() {
261         int i=1;
262         ArrayList<TypeAst> context;
263         if(get(i) instanceof Token)
264             context = new ArrayList<TypeAst>(0);
265         else
266             context = (ArrayList<TypeAst>)get(i++);
267         String name = ((Token)get(i++)).text;
268         ArrayList<String> parameters = new ArrayList<String>();
269         while(i < length()) {
270             Token token = (Token)get(i);
271             if(token.id != SCLTerminals.ID)
272                 break;
273             parameters.add(token.text);
274             ++i;
275         }
276         ArrayList<DeclarationAst> declarations = null;
277         FundepAst[] fundeps = FundepAst.EMPTY_ARRAY;
278         while(i < length()) {
279             Token token = (Token)get(i++);
280             if(token.id == SCLTerminals.WHERE) {
281                 declarations = (ArrayList<DeclarationAst>)get(i++);
282             }
283             else if(token.id == SCLTerminals.BAR) {
284                 fundeps = (FundepAst[])get(i++);
285             }
286             else
287                 throw new InternalCompilerError();
288         }
289         return new DClassAst(context, name,
290                 parameters.toArray(new String[parameters.size()]),
291                 fundeps,
292                 declarations);
293     }
294
295     @Override
296     protected Object reduceFundep() {
297         String[] from = new String[length()-2];
298         for(int i=0;i<from.length;++i)
299             from[i] = ((Token)get(i)).text;
300         String to = ((Token)get(length()-1)).text;
301         return new FundepAst(from, to);
302     }
303
304     @Override
305     protected Object reduceFundeps() {
306         FundepAst[] fundeps = new FundepAst[(length()+1)/2];
307         for(int i=0;i<fundeps.length;++i)
308             fundeps[i] = (FundepAst)get(i*2);
309         return fundeps;
310     }
311
312     @SuppressWarnings("unchecked")
313     @Override
314     protected Object reduceInstanceDefinition() {
315         int i=1;
316         ArrayList<TypeAst> context;
317         if(get(i) instanceof Token)
318             context = new ArrayList<TypeAst>(0);
319         else
320             context = (ArrayList<TypeAst>)get(i++);
321         Token nameToken = (Token)get(i++);
322         EVar name = new EVar(nameToken);
323         ArrayList<TypeAst> parameters = new ArrayList<TypeAst>();
324         while(i < length()) {
325             Object symbol = get(i++);
326             if(symbol instanceof Token)
327                 break;            
328             parameters.add((TypeAst)symbol);
329         }
330         ArrayList<DeclarationAst> declarations = null;
331         if(i < length())
332             declarations = (ArrayList<DeclarationAst>)get(i);
333         return new DInstanceAst(context, name,
334                 parameters.toArray(new TypeAst[parameters.size()]),
335                 declarations);
336     }
337
338     @SuppressWarnings("unchecked")
339     @Override
340     protected Object reduceDerivingInstanceDefinition() {
341         int i=2;
342         ArrayList<TypeAst> context;
343         if(get(i) instanceof Token)
344             context = new ArrayList<TypeAst>(0);
345         else
346             context = (ArrayList<TypeAst>)get(i++);
347         Token nameToken = (Token)get(i++);
348         EVar name = new EVar(nameToken);
349         ArrayList<TypeAst> parameters = new ArrayList<TypeAst>();
350         while(i < length()) {
351             Object symbol = get(i++);
352             parameters.add((TypeAst)symbol);
353         }
354         return new DDerivingInstanceAst(context, name,
355                 parameters.toArray(new TypeAst[parameters.size()]));
356     }
357
358     @Override
359     protected Object reduceDocumentationString() {
360         return new DDocumentationAst(((Token)get(1)).text);
361     }
362
363     @Override
364     protected Object reduceAnnotation() {
365         ArrayList<Expression> parameters = new ArrayList<Expression>(length()-1);
366         for(int i=1;i<length();++i)
367             parameters.add((Expression)get(i));
368         return new DAnnotationAst((Token)get(0), parameters);
369     }
370
371     @Override
372     protected Object reducePrecedenceDefinition() {
373         EVar[] symbols = new EVar[length()/2];
374         for(int i=0;i<symbols.length;++i)
375             symbols[i] = (EVar)get(2*i + 2);
376         Associativity associativity;
377         Token token = (Token)get(0);
378         if(token.text.equals("infixl"))
379             associativity = Associativity.LEFT;
380         else if(token.text.equals("infixr"))
381             associativity = Associativity.RIGHT;
382         else
383             associativity = Associativity.NONASSOC;
384         return new DFixityAst(
385                 new Precedence(
386                         Integer.parseInt(((Token)get(1)).text), 
387                         associativity), 
388                         symbols);
389     }
390
391     @Override
392     protected Object reduceImport() {
393         // (AS ID)? importSpec?
394         int pos = 0;
395         String importKeyword = ((Token)get(pos++)).text; // (IMPORT | INCLUDE) 
396         ++pos; // BEGIN_STRING
397         String moduleName = ((Token)get(pos++)).text; // END_STRING
398         String localName = "";
399         if(pos < length()) {
400             Object temp = get(pos);
401             if(temp instanceof Token) {
402                 Token token = (Token)temp;
403                 if(token.id == SCLTerminals.AS) {
404                     ++pos; // AS
405                     localName = ((Token)get(pos++)).text; // ID
406                 }
407             }
408         }
409         ImportDeclaration.ImportSpec spec = ImportDeclaration.DEFAULT_SPEC;
410         if(pos < length())
411             spec = (ImportDeclaration.ImportSpec)get(pos++);
412         return new ImportDeclaration(moduleName, localName,
413                         importKeyword.equals("include"),
414                         spec);
415     }
416
417     @Override
418     protected Object reduceJustImport() {
419         return get(0);
420     }
421
422     @SuppressWarnings("unchecked")
423     @Override
424     protected Object reduceImportJava() {
425         return new DImportJavaAst(((Token)get(2)).text, (ArrayList<DeclarationAst>)get(4));
426     }
427
428     @Override
429     protected Object reduceEffectDefinition() {
430         return new DEffectAst(
431                 ((Token)get(1)).text,
432                 ((Token)get(3)).text,
433                 ((Token)get(5)).text);
434     }
435
436     @Override
437     protected Object reduceVarId() {
438         return new EVar((Token)get(0));
439     }
440
441     @Override
442     protected Object reduceEscapedSymbol() {
443         return new EVar((Token)get(0));
444     }
445
446     @Override
447     protected Object reduceTupleTypeConstructor() {
448         return new TVarAst(Types.tupleConstructor(length()-1).name);
449     }
450
451     @Override
452     protected Object reduceArrow() {
453         int i=length()-1;
454         TypeAst result = (TypeAst)get(i);
455         i-=2;
456         while(i >= 0) {
457             if( ((Token)get(i+1)).text.equals("=>") )
458                 result = new TPredAst((TypeAst)get(i), result);
459             else
460                 result = new TFunctionAst((TypeAst)get(i), result);
461             i-=2;
462         }
463         return result;
464     }
465
466     @Override
467     protected Object reduceBinary() {
468         if(length() == 1)
469             return get(0);
470         int i=0;
471         EVar negation = null;
472         if(get(i) instanceof Token) {
473             Token token = (Token)get(i++);
474             negation = new EVar(token);
475         }
476         EBinary binary = new EBinary((Expression)get(i++), negation);
477         while(i < length()) {
478             EVar operator = (EVar)get(i++);
479             Expression right = (Expression)get(i++);
480             binary.rights.add(new EBinaryRightSide(operator, right));
481         }
482         return binary;
483     }
484
485     @Override
486     protected Object reduceSimpleRhs() {
487         if(length() == 2)
488             return get(1);
489         else {
490             EBlock block = (EBlock)get(3);
491             Expression expression = (Expression)get(1);
492             block.addStatement(new GuardStatement(expression));
493             block.location = Locations.location(Locations.beginOf(expression.location), Locations.endOf(block.location));
494             return block;
495         }
496     }
497
498     private GuardedExpressionGroup reduceGuardedExpressionGroup(int length) {
499         GuardedExpression[] expressions = new GuardedExpression[length];
500         for(int i=0;i<expressions.length;++i) {
501             expressions[i] = (GuardedExpression)get(i);
502         }
503         return new GuardedExpressionGroup(expressions);
504     }
505
506     @Override
507     protected Object reduceGuardedRhs() {
508         int length = length();
509         if(length > 2 && get(length-2) instanceof Token) {
510             EBlock block = (EBlock)get(length-1);
511             block.addStatement(new GuardStatement(reduceGuardedExpressionGroup(length-2)));
512             block.location = Locations.NO_LOCATION;
513             return block;
514         }
515         else
516             return reduceGuardedExpressionGroup(length);
517     }
518
519     @Override
520     protected Object reduceStatements() {
521         EBlock block = new EBlock();
522         if(length() > 2)
523             for(int i=1;i<length();i+=2)
524                 block.addStatement((Statement)get(i));
525         return block;
526     }
527
528     @Override
529     protected Object reduceConstructor() {
530         int idPos;
531         for(idPos=0;idPos<length();idPos+=2)
532             if(((Token)get(idPos)).id == SCLTerminals.ID)
533                 break;
534         DAnnotationAst[] annotations = idPos == 0 ? DAnnotationAst.EMPTY_ARRAY : new DAnnotationAst[idPos/2];
535         for(int i=0;i<idPos/2;++i)
536             annotations[i] = new DAnnotationAst((Token)get(i*2), 
537                     Arrays.asList((Expression)get(i*2+1)));
538         TypeAst[] parameters = new TypeAst[length()-idPos-1];
539         for(int i=0;i<parameters.length;++i)
540             parameters[i] = (TypeAst)get(i+idPos+1);
541         return new ConstructorAst(annotations, (Token)get(idPos), parameters, null);
542     }
543
544     @Override
545     protected Object reduceContext() {
546         ArrayList<TypeAst> result = new ArrayList<TypeAst>(length()/2-1);
547         for(int i=1;i<length()-2;i+=2)
548             result.add((TypeAst)get(i));
549         return result;
550     }
551
552     @Override
553     protected Object reduceTypeVar() {
554         return new TVarAst(((Token)get(0)).text);
555     }
556
557     @Override
558     protected Object reduceTupleType() {
559         if(length() == 2)
560             return new TTupleAst(TypeAst.EMPTY_ARRAY);
561         if(length() == 3) {
562             Symbol sym = (Symbol)get(1);
563             sym.location = Locations.NO_LOCATION;
564             return sym;
565         }
566         int dim = length()/2;
567         TypeAst[] parameters = new TypeAst[dim];
568         for(int i=0;i<dim;++i)
569             parameters[i] = (TypeAst)get(i*2+1);
570         return new TTupleAst(parameters);
571     }
572
573     @Override
574     protected Object reduceListType() {
575         return new TListAst((TypeAst)get(1));
576     }
577
578     @Override
579     protected Object reduceListTypeConstructor() {
580         return new TVarAst("[]");
581     }
582
583     @Override
584     protected Object reduceTupleConstructor() {
585         return new EVar(Types.tupleConstructor(length()-1).name);
586     }
587
588     @Override
589     protected Object reduceVar() {
590         return get(0);
591     }
592
593     @Override
594     protected Object reduceBlank() {
595         return new EVar(((Token)get(0)).location, "_");
596     }
597
598     @Override
599     protected Object reduceInteger() {
600         return new EIntegerLiteral(((Token)get(0)).text);
601     }
602
603     @Override
604     protected Object reduceFloat() {
605         return new ERealLiteral(((Token)get(0)).text);
606     }
607
608     @Override
609     protected Object reduceString() {
610         return get(0);
611     }
612
613     @Override
614     protected Object reduceChar() {
615         String text = ((Token)get(0)).text;
616         char c = text.charAt(text.length()-2);
617         if(text.length() == 4) {
618             switch(c) {
619             case 'n': c = '\n'; break;
620             case 't': c = '\t'; break;
621             case 'b': c = '\b'; break;
622             case 'f': c = '\f'; break;
623             case 'r': c = '\r'; break;
624             }
625         }
626         return new ELiteral(new CharacterConstant(c));
627     }
628
629     @Override
630     protected Object reduceTuple() {
631         if(length() == 2)
632             return new EConstant(Builtins.TUPLE_CONSTRUCTORS[0]);
633         if(length() == 3) {
634             Symbol sym = (Symbol)get(1);
635             sym.location = Locations.NO_LOCATION;
636             return sym;
637         }
638         int dim = length()/2;
639         Expression[] parameters = new Expression[dim];
640         for(int i=0;i<dim;++i)
641             parameters[i] = (Expression)get(i*2+1);
642         EConstant tupleConstructor = new EConstant(Builtins.TUPLE_CONSTRUCTORS[dim]);
643         tupleConstructor.location = Locations.location(
644                 Locations.beginOf(((Token)get(0)).location),
645                 Locations.endOf(((Token)get(length()-1)).location));
646         return new EApply(tupleConstructor, parameters);
647     }
648
649     public static Expression rightSection(EVar op, Expression e) {
650         long loc = Locations.combine(op.location, e.location);
651         Variable var = new Variable("rightSectionTemp");
652         return new ESimpleLambda(loc, var, 
653                 new EApply(loc, op, new EVariable(loc, var), e));
654     }
655
656     @Override
657     protected Object reduceRightSection() {
658         Variable var = new Variable("rightSectionTemp");
659         long loc = Locations.combine(((Token)get(0)).location, ((Token)get(length()-1)).location);
660         EVar symbol = (EVar)get(1);
661         return new ESimpleLambda(var, 
662                 new EApply(loc, symbol,
663                         new EVariable(loc, var), (Expression)get(2)));
664     }
665
666     @Override
667     protected Object reduceLeftSection() {
668         return new EApply((EVar)get(2), (Expression)get(1));
669     }
670
671     @Override
672     protected Object reduceListLiteral() {
673         if(length() == 2)
674             return new EListLiteral(Expression.EMPTY_ARRAY);
675         int dim = length()/2;
676         Expression[] components = new Expression[dim];
677         for(int i=0;i<dim;++i)
678             components[i] = (Expression)get(i*2+1);
679         return new EListLiteral(components);
680     }
681
682     @Override
683     protected Object reduceRange() {
684         return new ERange(
685                 (Expression)get(1),
686                 (Expression)get(3)
687                 );
688     }
689
690     @Override
691     protected Object reduceListComprehension() {
692         ListQualifier qualifier = (ListQualifier)get(3);
693         for(int i=5;i<length();i+=2) {
694             ListQualifier right = (ListQualifier)get(i);
695             if(right instanceof ListThen) {
696                 ((ListThen) right).setLeft(qualifier);
697                 qualifier = right;
698             }
699             else
700                 qualifier = new ListSeq(qualifier, right);
701         }
702         return new EListComprehension((Expression)get(1), qualifier);
703     }
704
705     @Override
706     protected Object reduceAs() {
707         Token id = (Token)get(0);
708         return new EAsPattern(new EVar(id.location, id.text), (Expression)get(2));
709     }
710
711     @Override
712     protected Object reduceGuardedExpEq() {
713         Expression[] guards = new Expression[length()/2-1];
714         for(int i=0;i<guards.length;++i)
715             guards[i] = (Expression)get(i*2+1);
716         return new GuardedExpression(guards, (Expression)get(length()-1));
717     }
718
719     @Override
720     protected Object reduceLambda() {
721         Expression[] patterns = new Expression[length()-3];
722         for(int i=0;i<patterns.length;++i)
723             patterns[i] = (Expression)get(i+1);
724         Case case_ = new Case(patterns, (Expression)get(length()-1));
725         case_.setLhs(Locations.combine(patterns[0].location, patterns[patterns.length-1].location));
726         return new ELambda(case_);
727     }
728     
729     @Override
730     protected Object reduceLambdaMatch() {
731         Case[] cases = new Case[length()/2-1];
732         for(int i=0;i<cases.length;++i)
733             cases[i] = (Case)get(i*2+2);
734         return new ELambda(cases);
735     }
736
737     @Override
738     protected Object reduceLet() {
739         EBlock block = (EBlock)get(1);
740         Expression expression = (Expression)get(3);
741         block.addStatement(new GuardStatement(expression));
742         Token letToken = (Token)get(0);
743         block.location = Locations.location(
744                 Locations.beginOf(letToken.location),
745                 Locations.endOf(expression.location));
746         return block;
747     }
748
749     @Override
750     protected Object reduceIf() {
751         return new EIf(
752                 (Expression)get(1),
753                 (Expression)get(3),
754                 length() == 6 ? (Expression)get(5) : null);
755     }
756
757     @Override
758     protected Object reduceMatch() {
759         Case[] cases = new Case[length()/2-2];
760         for(int i=0;i<cases.length;++i)
761             cases[i] = (Case)get(i*2+4);
762         return new EMatch((Expression)get(1), cases);
763     }
764
765     @Override
766     protected Object reduceDo() {
767         EBlock block = (EBlock)get(1);
768         Token doToken = (Token)get(0);
769         switch(doToken.text) {
770         case "mdo":
771             block.setBlockType(BlockType.Monad);
772             break;
773         case "edo":
774             block.setBlockType(BlockType.MonadE);
775             break;
776         }
777         block.location = Locations.location(Locations.beginOf(doToken.location), Locations.endOf(block.location));
778         return block;
779     }
780
781     @Override
782     protected Object reduceSelect() {
783         return new ESelect(((Token)get(0)).id, (Expression)get(1), new QConjunction((Query[])get(3)));
784     }
785        
786     @Override
787     protected Object reduceEnforce() {
788         return new EEnforce(new QConjunction((Query[])get(1)));
789     }
790
791     @Override
792     protected Object reduceApply() {
793         if(length() == 1)
794             return get(0);
795         Expression[] parameters = new Expression[length()-1];
796         for(int i=0;i<parameters.length;++i)
797             parameters[i] = (Expression)get(i+1);
798         return new EApply((Expression)get(0), parameters);
799     }
800
801     @Override
802     protected Object reduceSymbol() {
803         return new EVar(((Token)get(0)).text);
804     }
805
806     @Override
807     protected Object reduceEscapedId() {
808         return new EVar(((Token)get(0)).text);
809     }
810
811     @Override
812     protected Object reduceMinus() {
813         return new EVar(((Token)get(0)).text);
814     }
815
816     @Override
817     protected Object reduceLess() {
818         return new EVar(((Token)get(0)).text);
819     }
820
821     @Override
822     protected Object reduceGreater() {
823         return new EVar(((Token)get(0)).text);
824     }
825
826     @Override
827     protected Object reduceDot() {
828         return new EVar(((Token)get(0)).text);
829     }
830
831     @Override
832     protected Object reduceCase() {
833         return new Case((Expression)get(0), (Expression)get(1));
834     }
835
836     @Override
837     protected Object reduceGuardQualifier() {
838         return new ListGuard((Expression)get(0));
839     }
840
841     @Override
842     protected Object reduceLetQualifier() {
843         return new ListAssignment((Expression)get(0), (Expression)get(2));
844     }
845
846     @Override
847     protected Object reduceBindQualifier() {
848         return new ListGenerator((Expression)get(0), (Expression)get(2));
849     }
850
851     @Override
852     protected Object reduceThenQualifier() {
853         return new ListThen((Expression)get(1), length()==4 ? (Expression)get(3) : null);
854     }
855
856     @Override
857     protected Object reduceGuardStatement() {
858         return new GuardStatement((Expression)get(0));
859     }
860
861     @Override
862     protected Object reduceLetStatement() {
863         return new LetStatement((Expression)get(0), (Expression)get(1));
864     }
865
866     @Override
867     protected Object reduceBindStatement() {
868         return new BindStatement((Expression)get(0), (Expression)get(2));
869     }
870
871     @Override
872     protected Object reduceSimpleCaseRhs() {
873         return get(1);
874     }
875
876     @Override
877     protected Object reduceGuardedCaseRhs() {
878         GuardedExpression[] expressions = new GuardedExpression[length()];
879         for(int i=0;i<expressions.length;++i)
880             expressions[i] = (GuardedExpression)get(i);
881         return new GuardedExpressionGroup(expressions);
882     }
883
884     @Override
885     protected Object reduceGuardedExpArrow() {
886         Expression[] guards = new Expression[length()/2-1];
887         for(int i=0;i<guards.length;++i)
888             guards[i] = (Expression)get(i*2+1);
889         return new GuardedExpression(guards, (Expression)get(length()-1));
890     }
891
892     @Override
893     protected Object reduceEffect() {
894         ArrayList<TypeAst> effects = new ArrayList<TypeAst>(length()/2-1);
895         for(int i=1;i<length()-1;i+=2) {
896             Token token = (Token)get(i);
897             TVarAst ast = new TVarAst(token.text);
898             ast.location = token.location;
899             effects.add(ast);
900         }
901         return new TEffectAst(effects, (TypeAst)get(length()-1));
902     }
903
904     @Override
905     protected Object reduceJustEtype() {
906         return get(0);
907     }
908
909     @Override
910     protected Object reduceForAll() {
911         String[] vars = new String[length()-3];
912         for(int i=0;i<vars.length;++i)
913             vars[i] = ((Token)get(i+1)).text;
914         return new TForAllAst(vars, (TypeAst)get(length()-1));
915     }
916
917     @Override
918     protected Object reduceApplyType() {
919         TypeAst[] parameters = new TypeAst[length()-1];
920         for(int i=0;i<parameters.length;++i)
921             parameters[i] = (TypeAst)get(i+1);
922         return new TApplyAst((TypeAst)get(0), parameters);
923     }
924
925     @SuppressWarnings("unchecked")
926     @Override
927     protected void postReduce(Object reduced) {
928         if(!(reduced instanceof Symbol))
929             return;
930         Symbol sym = (Symbol)reduced;
931         if(sym.location != Locations.NO_LOCATION || length() == 0)
932             return;
933         Object first = get(0);
934         if(!(first instanceof Symbol)) {
935             if(first instanceof List) {
936                 List<Object> ll = (List<Object>)first;
937                 first = ll.get(0);
938             }
939             else {
940                 Object[] ll = (Object[])first;
941                 if(ll.length > 0)
942                     first = ll[0];
943                 else
944                     first = get(1);
945             }
946         }
947         Object last = get(length()-1);
948         if(!(last instanceof Symbol)) {
949             if(last instanceof List) {
950                 List<Object> ll = (List<Object>)last;
951                 last = ll.get(ll.size()-1);
952             }
953             else {
954                 Object[] ll = (Object[])last;
955                 if(ll.length > 0)
956                     last = ll[ll.length-1];
957                 else
958                     last = get(length()-2);
959             }
960         }
961         sym.location = (((Symbol)first).location & 0xffffffff00000000L) 
962                 | (((Symbol)last).location & 0xffffffffL);
963         /*for(int i=0;i<length();++i) {
964             Object obj = get(i);
965             System.out.print(obj.getClass().getSimpleName());
966             if(obj instanceof Token) {
967                 Token t = (Token)obj;
968                 System.out.print("(" + t.text + ")");
969             }
970             if(obj instanceof Symbol) {
971                 Symbol s = (Symbol)obj;
972                 System.out.print("["+ Locations.beginOf(s.location) + "-" + Locations.endOf(s.location) + "]");
973             }
974             System.out.print(" ");
975         }
976         System.out.println("-> " + reduced.getClass().getSimpleName() + " " +
977                 Locations.beginOf(sym.location) + "-" + Locations.endOf(sym.location));*/
978     }
979
980     @Override
981     protected RuntimeException syntaxError(Token token, String description) {
982         throw new SCLSyntaxErrorException(token.location, description);
983     }
984
985     @Override
986     protected Object reduceIdAccessor() {
987         return new IdAccessor('.', ((Token)get(0)).text);
988     }
989
990     @Override
991     protected Object reduceStringAccessor() {
992         return new StringAccessor('.', ((Token)get(1)).text);
993     }
994
995     @Override
996     protected Object reduceExpAccessor() {
997         return new ExpressionAccessor('.', (Expression)get(1));
998     }
999
1000     @Override
1001     protected Object reduceFieldAccess() {
1002         if(length() == 1)
1003             return get(0);
1004         Expression result = (Expression)get(0);
1005         for(int i=2;i<length();i+=2) {
1006             FieldAccessor accessor = (FieldAccessor)get(i);
1007             accessor.accessSeparator = ((Token)get(i-1)).text.charAt(0);
1008             result = new EFieldAccess(result, accessor);
1009         }
1010         return result;
1011     }
1012
1013     @Override
1014     protected Object reduceQueryBlock() {
1015         if(length() == 2)
1016             return Query.EMPTY_ARRAY;
1017         Query[] queries = new Query[length()/2];
1018         for(int i=0;i<queries.length;++i)
1019             queries[i] = (Query)get(2*i+1);
1020         return queries;
1021     }
1022
1023     @Override
1024     protected Object reduceGuardQuery() {
1025         return new QPreGuard((Expression)get(0));
1026     }
1027
1028     @Override
1029     protected Object reduceEqualsQuery() {
1030         return new QPreEquals((Expression)get(0), (Expression)get(2));
1031     }
1032
1033     @Override
1034     protected Object reduceBindQuery() {
1035         return new QPreBinds((Expression)get(0), (Expression)get(2));
1036     }
1037
1038     @Override
1039     protected Object reduceCompositeQuery() {
1040         Query[] queries = (Query[])get(1);
1041         switch(((Token)get(0)).text.charAt(1)) {
1042         case '&': return new QConjunction(queries);
1043         case '|': return new QDisjunction(queries);
1044         case '!': return new QNegation(new QConjunction(queries));
1045         case '?': return new QAlternative(queries);
1046         default: throw new InternalCompilerError();
1047         }
1048     }
1049     
1050     @Override
1051     protected Object reduceRuleStatement() {
1052         return new RuleStatement((Expression)get(0), new QConjunction((Query[])get(2)));
1053     }
1054
1055     @Override
1056     protected Object reduceHashedId() {
1057         return new EVar("#" + ((Token)get(1)).text);
1058     }
1059
1060     @Override
1061     protected Object reduceStringLiteral() {
1062         int expCount = length()/3;
1063         if(expCount == 0)
1064             return new ELiteral(new StringConstant(((Token)get(1)).text));
1065         else {
1066             String[] strings = new String[expCount+1];
1067             Expression[] expressions = new Expression[expCount];
1068             for(int i=0;i<expCount;++i) {
1069                 strings[i] = ((Token)get(i*3+1)).text;
1070                 expressions[i] = (Expression)get(i*3+2);
1071             }
1072             strings[expCount] = ((Token)get(expCount*3+1)).text;
1073             return new EStringLiteral(strings, expressions);
1074         }
1075     }
1076
1077     @Override
1078     protected Object reduceOneCommand() {
1079         return null;
1080     }
1081     
1082     @Override
1083     protected Object reduceManyCommands() {
1084         return null;
1085     }
1086
1087     @Override
1088     protected Object reduceStatementCommand() {
1089         // to be extended in subclasses
1090         return null;
1091     }
1092
1093     @Override
1094     protected Object reduceImportCommand() {
1095         // to be extended in subclasses
1096         return null;
1097     }
1098     
1099     @Override
1100     protected Object reduceImportValueItem() {
1101         return new EVar(((Token)get(0)).text);
1102     }
1103     
1104     @Override
1105     protected Object reduceImportHiding() {
1106         EVar[] values = new EVar[(length()-2)/2];
1107         for(int i=0;i<values.length;++i)
1108             values[i] = (EVar)get(i*2+2);
1109         return new ImportDeclaration.ImportSpec(true, values);
1110     }
1111     
1112     @Override
1113     protected Object reduceImportShowing() {
1114         EVar[] values = new EVar[(length()-1)/2];
1115         for(int i=0;i<values.length;++i)
1116             values[i] = (EVar)get(i*2+1);
1117         return new ImportDeclaration.ImportSpec(false, values);
1118     }
1119
1120     @Override
1121     protected Object reduceRuleDeclarations() {
1122         ArrayList<Object> declarations = new ArrayList<Object>(length()/2);
1123         for(int i=1;i<length();i+=2)
1124             declarations.add((Object)get(i));
1125         return declarations;
1126     }
1127
1128     private static final String[] EMPTY_STRING_ARRAY = new String[0];
1129     
1130     @SuppressWarnings("unchecked")
1131     @Override
1132     protected Object reduceRuleDefinition() {
1133         String[] extendsNames = EMPTY_STRING_ARRAY;
1134         if(length() >= 6) {
1135             int extendsCount = (length() - 4) / 2;
1136             extendsNames = new String[extendsCount]; 
1137             for(int i=0;i<extendsCount;++i)
1138                 extendsNames[i] = ((Token)get(3+i*2)).text;
1139         }
1140         
1141         DRuleAst rule = new DRuleAst(
1142                 ((Token)get(0)).id == SCLTerminals.ABSTRACT_RULE,
1143                 ((Token)get(1)).text,
1144                 extendsNames);
1145         
1146         ArrayList<Object> ruleDeclarations = (ArrayList<Object>)get(length()-1);
1147         ArrayList<Query> section = null;
1148         for(Object decl : ruleDeclarations) {
1149             if(decl instanceof DAnnotationAst) {
1150                 DAnnotationAst annotation = (DAnnotationAst)decl;
1151                 section = rule.getSection(annotation.id.text.substring(1));
1152             }
1153             else if(decl instanceof Query) {
1154                 if(section == null)
1155                     section = rule.getSection("when");
1156                 section.add((Query)decl);
1157             }
1158             else
1159                 throw new InternalCompilerError();
1160         }
1161         return rule;
1162     }
1163
1164     @Override
1165     protected Object reduceQueryRuleDeclaration() {
1166         return get(0);
1167     }
1168
1169     @Override
1170     protected Object reduceMappingRelationDefinition() {
1171         TypeAst[] types = new TypeAst[length()-2];
1172         for(int i=0;i<types.length;++i)
1173             types[i] = (TypeAst)get(i+2);
1174         return new DMappingRelationAst(
1175                 ((Token)get(1)).text,
1176                 types);
1177     }
1178
1179     @Override
1180     protected Object reduceTransformation() {
1181         return new ETransformation(
1182                 ((Token)get(1)).text,
1183                 new QConjunction((Query[])get(3))
1184                 );
1185     }
1186
1187     @SuppressWarnings("unchecked")
1188     @Override
1189     protected Object reduceRelationDefinition() {
1190         return new DRelationAst((Expression)get(0), 
1191                 ((ArrayList<Object>)get(2)).toArray());
1192     }
1193
1194     @Override
1195     protected Object reduceRecord() {
1196         FieldAssignment[] fields = new FieldAssignment[length()/2-1];
1197         for(int i=0;i<fields.length;++i)
1198             fields[i] = (FieldAssignment)get(2+i*2);
1199         return new ERecord(new EVar((Token)get(0)), fields);
1200     }
1201
1202     @Override
1203     protected Object reduceField() {
1204         return new FieldAssignment(((Token)get(0)).text, (Expression)get(2));
1205     }
1206     
1207     @Override
1208     protected Object reduceFieldShorthand() {
1209         return new FieldAssignment(((Token)get(0)).text, null);
1210     }
1211
1212     @Override
1213     protected Object reduceRecordConstructor() {
1214         int idPos;
1215         for(idPos=0;idPos<length();idPos+=2)
1216             if(((Token)get(idPos)).id == SCLTerminals.ID)
1217                 break;
1218         DAnnotationAst[] annotations = idPos == 0 ? DAnnotationAst.EMPTY_ARRAY : new DAnnotationAst[idPos/2];
1219         for(int i=0;i<idPos/2;++i)
1220             annotations[i] = new DAnnotationAst((Token)get(i*2), 
1221                     Arrays.asList((Expression)get(i*2+1)));
1222         TypeAst[] parameters = new TypeAst[(length()-idPos-1)/2];
1223         String[] fieldNames = new String[parameters.length];
1224         for(int i=0;i<parameters.length;++i) {
1225             FieldDescription fieldDesc = (FieldDescription)get(idPos+(i+1)*2);
1226             parameters[i] = fieldDesc.type;
1227             fieldNames[i] = fieldDesc.name;
1228         }
1229         return new ConstructorAst(annotations, (Token)get(idPos), parameters, fieldNames);
1230     }
1231
1232     @Override
1233     protected Object reduceFieldDescription() {
1234         return new FieldDescription(((Token)get(0)).text, (TypeAst)get(2));
1235     }
1236
1237     @Override
1238     protected Object reduceEq() {
1239         return (Expression)get(2);
1240     }
1241
1242     @Override
1243     protected Object reduceEquationBlock() {
1244         if(length() == 0)
1245             return new EEquations(Equation.EMPTY_ARRAY);
1246         Equation[] equations = new Equation[length()/2+1];
1247         for(int i=0;i<equations.length;++i)
1248             equations[i] = (Equation)get(2*i);
1249         return new EEquations(equations);
1250     }
1251
1252     @Override
1253     protected Object reduceGuardEquation() {
1254         return new EqGuard((Expression)get(0));
1255     }
1256
1257     @Override
1258     protected Object reduceBasicEquation() {
1259         return new EqBasic((Expression)get(0), (Expression)get(2));
1260     }
1261
1262     @Override
1263     protected Object reduceViewPattern() {
1264         return new EViewPattern((Expression)get(1), (Expression)get(3));
1265     }
1266
1267     @Override
1268     protected Object reduceConstraintStatement() {
1269         ConstructorAst constructor = (ConstructorAst)get(1);
1270         return new ConstraintStatement(constructor.name, constructor.parameters, constructor.fieldNames, constructor.annotations);
1271     }
1272
1273     /*
1274     @Override
1275     protected Object reduceWhen() {
1276         return new EWhen(
1277                 new QConjunction((Query[])get(1)),
1278                 (Expression)get(3));
1279     }*/
1280
1281     @Override
1282     protected Object reduceDummy() {
1283         throw new UnsupportedOperationException();
1284     }
1285
1286     @Override
1287     protected Object reduceRulesetDefinition() {
1288         Token name = (Token)get(1);
1289         EBlock block = (EBlock)get(3);
1290         return new DRulesetAst(name.text, block);
1291     }
1292
1293     @Override
1294     protected Object reduceLocalInclude() {
1295         Token name = (Token)get(1);
1296         Expression value = (Expression)get(2);
1297         return new IncludeStatement(name, value);
1298     }
1299
1300     /*@Override
1301     protected Object reduceConstraintSpec() {
1302         Expression[] expressions = new Expression[length()/2-1];
1303         for(int i=0;i<expressions.length;++i)
1304             expressions[i] = (Expression)get(2*i+1);
1305         return expressions;
1306     }*/
1307
1308     @Override
1309     protected Object reduceCHRSelect() {
1310         return new EPreCHRSelect((CHRAstQuery)get(3), (Expression)get(1));
1311     }
1312
1313     @Override
1314     protected Object reduceCHRAtom() {
1315         return CHRAstAtom.atom((Expression)get(0));
1316     }
1317
1318     @Override
1319     protected Object reduceCHREquals() {
1320         return new CHRAstEquals((Expression)get(0), (Expression)get(2));
1321     }
1322
1323     @Override
1324     protected Object reduceCHRBinds() {
1325         return new CHRAstBinds((Expression)get(0), (Expression)get(2));
1326     }
1327
1328     @Override
1329     protected Object reduceCHRConjunction() {
1330         CHRAstQuery[] conjuncts = new CHRAstQuery[(length()+1)/2];
1331         for(int i=0;i<conjuncts.length;++i)
1332             conjuncts[i] = (CHRAstQuery)get(i*2);
1333         return CHRAstConjunction.conjunction(conjuncts);
1334     }
1335     
1336     @Override
1337     protected Object reduceVerboseCHRConjunction() {
1338         CHRAstQuery[] conjuncts = new CHRAstQuery[(length()-1)/2];
1339         for(int i=0;i<conjuncts.length;++i)
1340             conjuncts[i] = (CHRAstQuery)get(i*2+1);
1341         return CHRAstConjunction.conjunction(conjuncts);
1342     }
1343     
1344     @Override
1345     protected Object reduceVerboseCHRStatement() {
1346         return new CHRStatement((CHRAstQuery)get(1), (CHRAstQuery)get(3));
1347     }
1348
1349     @Override
1350     protected Object reduceCHRStatement() {
1351         return new CHRStatement((CHRAstQuery)get(0), (CHRAstQuery)get(2));
1352     }
1353
1354     @Override
1355     protected Object reduceWildcard() {
1356         return new FieldAssignment(FieldAssignment.WILDCARD, null);
1357     }
1358
1359 }