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