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