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