1 package org.simantics.scl.compiler.internal.parsing.parser;
4 import java.util.ArrayList;
5 import java.util.Arrays;
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.equation.EqBasic;
15 import org.simantics.scl.compiler.elaboration.equation.EqGuard;
16 import org.simantics.scl.compiler.elaboration.equation.Equation;
17 import org.simantics.scl.compiler.elaboration.expressions.Case;
18 import org.simantics.scl.compiler.elaboration.expressions.EApply;
19 import org.simantics.scl.compiler.elaboration.expressions.EAsPattern;
20 import org.simantics.scl.compiler.elaboration.expressions.EBinary;
21 import org.simantics.scl.compiler.elaboration.expressions.EBinaryRightSide;
22 import org.simantics.scl.compiler.elaboration.expressions.EBlock;
23 import org.simantics.scl.compiler.elaboration.expressions.EConstant;
24 import org.simantics.scl.compiler.elaboration.expressions.EEnforce;
25 import org.simantics.scl.compiler.elaboration.expressions.EEquations;
26 import org.simantics.scl.compiler.elaboration.expressions.EFieldAccess;
27 import org.simantics.scl.compiler.elaboration.expressions.EIf;
28 import org.simantics.scl.compiler.elaboration.expressions.EIntegerLiteral;
29 import org.simantics.scl.compiler.elaboration.expressions.ELambda;
30 import org.simantics.scl.compiler.elaboration.expressions.EListComprehension;
31 import org.simantics.scl.compiler.elaboration.expressions.EListLiteral;
32 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
33 import org.simantics.scl.compiler.elaboration.expressions.EMatch;
34 import org.simantics.scl.compiler.elaboration.expressions.ERange;
35 import org.simantics.scl.compiler.elaboration.expressions.ERealLiteral;
36 import org.simantics.scl.compiler.elaboration.expressions.ERecord;
37 import org.simantics.scl.compiler.elaboration.expressions.ESelect;
38 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
39 import org.simantics.scl.compiler.elaboration.expressions.EStringLiteral;
40 import org.simantics.scl.compiler.elaboration.expressions.ETransformation;
41 import org.simantics.scl.compiler.elaboration.expressions.ETypeAnnotation;
42 import org.simantics.scl.compiler.elaboration.expressions.EVar;
43 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
44 import org.simantics.scl.compiler.elaboration.expressions.EViewPattern;
45 import org.simantics.scl.compiler.elaboration.expressions.Expression;
46 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpression;
47 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpressionGroup;
48 import org.simantics.scl.compiler.elaboration.expressions.Variable;
49 import org.simantics.scl.compiler.elaboration.expressions.accessor.ExpressionAccessor;
50 import org.simantics.scl.compiler.elaboration.expressions.accessor.FieldAccessor;
51 import org.simantics.scl.compiler.elaboration.expressions.accessor.IdAccessor;
52 import org.simantics.scl.compiler.elaboration.expressions.accessor.StringAccessor;
53 import org.simantics.scl.compiler.elaboration.expressions.block.BindStatement;
54 import org.simantics.scl.compiler.elaboration.expressions.block.CHRStatement;
55 import org.simantics.scl.compiler.elaboration.expressions.block.ConstraintStatement;
56 import org.simantics.scl.compiler.elaboration.expressions.block.GuardStatement;
57 import org.simantics.scl.compiler.elaboration.expressions.block.IncludeStatement;
58 import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement;
59 import org.simantics.scl.compiler.elaboration.expressions.block.RuleStatement;
60 import org.simantics.scl.compiler.elaboration.expressions.block.Statement;
61 import org.simantics.scl.compiler.elaboration.expressions.list.ListAssignment;
62 import org.simantics.scl.compiler.elaboration.expressions.list.ListGenerator;
63 import org.simantics.scl.compiler.elaboration.expressions.list.ListGuard;
64 import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifier;
65 import org.simantics.scl.compiler.elaboration.expressions.list.ListSeq;
66 import org.simantics.scl.compiler.elaboration.expressions.list.ListThen;
67 import org.simantics.scl.compiler.elaboration.expressions.records.FieldAssignment;
68 import org.simantics.scl.compiler.elaboration.java.Builtins;
69 import org.simantics.scl.compiler.elaboration.query.QAlternative;
70 import org.simantics.scl.compiler.elaboration.query.QConjunction;
71 import org.simantics.scl.compiler.elaboration.query.QDisjunction;
72 import org.simantics.scl.compiler.elaboration.query.QNegation;
73 import org.simantics.scl.compiler.elaboration.query.Query;
74 import org.simantics.scl.compiler.elaboration.query.pre.QPreBinds;
75 import org.simantics.scl.compiler.elaboration.query.pre.QPreEquals;
76 import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard;
77 import org.simantics.scl.compiler.errors.Locations;
78 import org.simantics.scl.compiler.internal.header.ModuleHeader;
79 import org.simantics.scl.compiler.internal.parsing.Symbol;
80 import org.simantics.scl.compiler.internal.parsing.Token;
81 import org.simantics.scl.compiler.internal.parsing.declarations.ConstructorAst;
82 import org.simantics.scl.compiler.internal.parsing.declarations.DAnnotationAst;
83 import org.simantics.scl.compiler.internal.parsing.declarations.DClassAst;
84 import org.simantics.scl.compiler.internal.parsing.declarations.DDataAst;
85 import org.simantics.scl.compiler.internal.parsing.declarations.DDerivingInstanceAst;
86 import org.simantics.scl.compiler.internal.parsing.declarations.DDocumentationAst;
87 import org.simantics.scl.compiler.internal.parsing.declarations.DEffectAst;
88 import org.simantics.scl.compiler.internal.parsing.declarations.DFixityAst;
89 import org.simantics.scl.compiler.internal.parsing.declarations.DImportJavaAst;
90 import org.simantics.scl.compiler.internal.parsing.declarations.DInstanceAst;
91 import org.simantics.scl.compiler.internal.parsing.declarations.DMappingRelationAst;
92 import org.simantics.scl.compiler.internal.parsing.declarations.DRelationAst;
93 import org.simantics.scl.compiler.internal.parsing.declarations.DRuleAst;
94 import org.simantics.scl.compiler.internal.parsing.declarations.DRulesetAst;
95 import org.simantics.scl.compiler.internal.parsing.declarations.DTypeAst;
96 import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst;
97 import org.simantics.scl.compiler.internal.parsing.declarations.DValueTypeAst;
98 import org.simantics.scl.compiler.internal.parsing.declarations.DeclarationAst;
99 import org.simantics.scl.compiler.internal.parsing.declarations.FieldDescription;
100 import org.simantics.scl.compiler.internal.parsing.declarations.FundepAst;
101 import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
102 import org.simantics.scl.compiler.internal.parsing.types.TApplyAst;
103 import org.simantics.scl.compiler.internal.parsing.types.TEffectAst;
104 import org.simantics.scl.compiler.internal.parsing.types.TForAllAst;
105 import org.simantics.scl.compiler.internal.parsing.types.TFunctionAst;
106 import org.simantics.scl.compiler.internal.parsing.types.TListAst;
107 import org.simantics.scl.compiler.internal.parsing.types.TPredAst;
108 import org.simantics.scl.compiler.internal.parsing.types.TTupleAst;
109 import org.simantics.scl.compiler.internal.parsing.types.TVarAst;
110 import org.simantics.scl.compiler.internal.parsing.types.TypeAst;
111 import org.simantics.scl.compiler.module.ImportDeclaration;
112 import org.simantics.scl.compiler.types.Types;
115 public class SCLParserImpl extends SCLParser {
117 private final SCLPostLexer lexer;
118 private SCLParserOptions options;
119 private CompilationContext context;
121 public SCLParserImpl(Reader reader) {
122 this.lexer = new SCLPostLexer(reader);
125 public void setCompilationContext(CompilationContext context) {
126 this.context = context;
127 lexer.setCompilationContext(context);
130 public void setParserOptions(SCLParserOptions options) {
131 this.options = options;
132 lexer.setParserOptions(options);
135 public boolean isEmpty() throws Exception {
136 return lexer.peekToken().id == SCLTerminals.EOF;
140 protected Token nextToken() {
142 Token token = lexer.nextToken();
143 /*System.out.println("TOKEN " + token.text + " (" + TERMINAL_NAMES[token.id] + ")" +
145 + Locations.beginOf(token.location) + ".."
146 + Locations.endOf(token.location) + "]");*/
148 } catch(Exception e) {
149 if(e instanceof RuntimeException)
150 throw (RuntimeException)e;
152 throw new RuntimeException(e);
157 protected Object reduceDeclarations() {
158 ArrayList<DeclarationAst> declarations = new ArrayList<DeclarationAst>(length()/2);
159 for(int i=1;i<length();i+=2)
160 declarations.add((DeclarationAst)get(i));
165 protected Object reduceModule() {
166 ArrayList<DeclarationAst> declarations = new ArrayList<DeclarationAst>(length()/2+1);
167 for(int i=0;i<length();i+=2) {
168 DeclarationAst declaration = (DeclarationAst)get(i);
169 if(declaration == null)
171 declarations.add(declaration);
177 protected Object reduceModuleHeader() {
178 FieldAssignment[] fields = new FieldAssignment[length()/2-1];
179 for(int i=0;i<fields.length;++i)
180 fields[i] = (FieldAssignment)get(2+i*2);
181 context.header = ModuleHeader.process(context.errorLog, fields);
186 protected Object reduceLocalTypeAnnotation() {
189 return new ETypeAnnotation((Expression)get(0), (TypeAst)get(2));
193 protected Object reduceTypeAnnotation() {
194 EVar[] names = new EVar[length()/2];
195 for(int i=0;i<names.length;++i)
196 names[i] = (EVar)get(i*2);
197 return new DValueTypeAst(
199 (TypeAst)get(length()-1)
204 protected Object reduceValueDefinition() {
205 Expression rhs = (Expression)get(1);
206 return new DValueAst((Expression)get(0), rhs);
210 protected Object reduceDataDefinition() {
212 ArrayList<String> parameters = new ArrayList<String>();
213 while(i < length()) {
214 Token token = (Token)get(i++);
215 if(token.id != SCLTerminals.ID)
217 parameters.add(token.text);
219 ArrayList<ConstructorAst> constructors = new ArrayList<ConstructorAst>();
220 for(;i < length();i+=2)
221 constructors.add((ConstructorAst)get(i));
223 ((Token)get(1)).text,
224 parameters.toArray(new String[parameters.size()]),
225 constructors.toArray(new ConstructorAst[constructors.size()]),
231 protected Object reduceTypeDefinition() {
233 ArrayList<String> parameters = new ArrayList<String>();
235 Token token = (Token)get(i++);
236 if(token.id != SCLTerminals.ID)
238 parameters.add(token.text);
241 ((Token)get(1)).text,
242 parameters.toArray(new String[parameters.size()]),
247 @SuppressWarnings("unchecked")
249 protected Object reduceClassDefinition() {
251 ArrayList<TypeAst> context;
252 if(get(i) instanceof Token)
253 context = new ArrayList<TypeAst>(0);
255 context = (ArrayList<TypeAst>)get(i++);
256 String name = ((Token)get(i++)).text;
257 ArrayList<String> parameters = new ArrayList<String>();
258 while(i < length()) {
259 Token token = (Token)get(i);
260 if(token.id != SCLTerminals.ID)
262 parameters.add(token.text);
265 ArrayList<DeclarationAst> declarations = null;
266 FundepAst[] fundeps = FundepAst.EMPTY_ARRAY;
267 while(i < length()) {
268 Token token = (Token)get(i++);
269 if(token.id == SCLTerminals.WHERE) {
270 declarations = (ArrayList<DeclarationAst>)get(i++);
272 else if(token.id == SCLTerminals.BAR) {
273 fundeps = (FundepAst[])get(i++);
276 throw new InternalCompilerError();
278 return new DClassAst(context, name,
279 parameters.toArray(new String[parameters.size()]),
285 protected Object reduceFundep() {
286 String[] from = new String[length()-2];
287 for(int i=0;i<from.length;++i)
288 from[i] = ((Token)get(i)).text;
289 String to = ((Token)get(length()-1)).text;
290 return new FundepAst(from, to);
294 protected Object reduceFundeps() {
295 FundepAst[] fundeps = new FundepAst[(length()+1)/2];
296 for(int i=0;i<fundeps.length;++i)
297 fundeps[i] = (FundepAst)get(i*2);
301 @SuppressWarnings("unchecked")
303 protected Object reduceInstanceDefinition() {
305 ArrayList<TypeAst> context;
306 if(get(i) instanceof Token)
307 context = new ArrayList<TypeAst>(0);
309 context = (ArrayList<TypeAst>)get(i++);
310 Token nameToken = (Token)get(i++);
311 EVar name = new EVar(nameToken);
312 ArrayList<TypeAst> parameters = new ArrayList<TypeAst>();
313 while(i < length()) {
314 Object symbol = get(i++);
315 if(symbol instanceof Token)
317 parameters.add((TypeAst)symbol);
319 ArrayList<DeclarationAst> declarations = null;
321 declarations = (ArrayList<DeclarationAst>)get(i);
322 return new DInstanceAst(context, name,
323 parameters.toArray(new TypeAst[parameters.size()]),
327 @SuppressWarnings("unchecked")
329 protected Object reduceDerivingInstanceDefinition() {
331 ArrayList<TypeAst> context;
332 if(get(i) instanceof Token)
333 context = new ArrayList<TypeAst>(0);
335 context = (ArrayList<TypeAst>)get(i++);
336 Token nameToken = (Token)get(i++);
337 EVar name = new EVar(nameToken);
338 ArrayList<TypeAst> parameters = new ArrayList<TypeAst>();
339 while(i < length()) {
340 Object symbol = get(i++);
341 parameters.add((TypeAst)symbol);
343 return new DDerivingInstanceAst(context, name,
344 parameters.toArray(new TypeAst[parameters.size()]));
348 protected Object reduceDocumentationString() {
349 return new DDocumentationAst(((Token)get(1)).text);
353 protected Object reduceAnnotation() {
354 ArrayList<Expression> parameters = new ArrayList<Expression>(length()-1);
355 for(int i=1;i<length();++i)
356 parameters.add((Expression)get(i));
357 return new DAnnotationAst((Token)get(0), parameters);
361 protected Object reducePrecedenceDefinition() {
362 EVar[] symbols = new EVar[length()/2];
363 for(int i=0;i<symbols.length;++i)
364 symbols[i] = (EVar)get(2*i + 2);
365 Associativity associativity;
366 Token token = (Token)get(0);
367 if(token.text.equals("infixl"))
368 associativity = Associativity.LEFT;
369 else if(token.text.equals("infixr"))
370 associativity = Associativity.RIGHT;
372 associativity = Associativity.NONASSOC;
373 return new DFixityAst(
375 Integer.parseInt(((Token)get(1)).text),
381 protected Object reduceImport() {
382 // (AS ID)? importSpec?
384 String importKeyword = ((Token)get(pos++)).text; // (IMPORT | INCLUDE)
385 ++pos; // BEGIN_STRING
386 String moduleName = ((Token)get(pos++)).text; // END_STRING
387 String localName = "";
389 Object temp = get(pos);
390 if(temp instanceof Token) {
391 Token token = (Token)temp;
392 if(token.id == SCLTerminals.AS) {
394 localName = ((Token)get(pos++)).text; // ID
398 ImportDeclaration.ImportSpec spec = ImportDeclaration.DEFAULT_SPEC;
400 spec = (ImportDeclaration.ImportSpec)get(pos++);
401 return new ImportDeclaration(moduleName, localName,
402 importKeyword.equals("include"),
407 protected Object reduceJustImport() {
411 @SuppressWarnings("unchecked")
413 protected Object reduceImportJava() {
414 return new DImportJavaAst(((Token)get(2)).text, (ArrayList<DeclarationAst>)get(4));
418 protected Object reduceEffectDefinition() {
419 return new DEffectAst(
420 ((Token)get(1)).text,
421 ((Token)get(3)).text,
422 ((Token)get(5)).text);
426 protected Object reduceVarId() {
427 return new EVar((Token)get(0));
431 protected Object reduceEscapedSymbol() {
432 return new EVar((Token)get(0));
436 protected Object reduceTupleTypeConstructor() {
437 return new TVarAst(Types.tupleConstructor(length()-1).name);
441 protected Object reduceArrow() {
443 TypeAst result = (TypeAst)get(i);
446 if( ((Token)get(i+1)).text.equals("=>") )
447 result = new TPredAst((TypeAst)get(i), result);
449 result = new TFunctionAst((TypeAst)get(i), result);
456 protected Object reduceBinary() {
460 EVar negation = null;
461 if(get(i) instanceof Token) {
462 Token token = (Token)get(i++);
463 negation = new EVar(token);
465 EBinary binary = new EBinary((Expression)get(i++), negation);
466 while(i < length()) {
467 EVar operator = (EVar)get(i++);
468 Expression right = (Expression)get(i++);
469 binary.rights.add(new EBinaryRightSide(operator, right));
475 protected Object reduceSimpleRhs() {
479 EBlock block = (EBlock)get(3);
480 Expression expression = (Expression)get(1);
481 block.addStatement(new GuardStatement(expression));
482 block.location = Locations.location(Locations.beginOf(expression.location), Locations.endOf(block.location));
487 private GuardedExpressionGroup reduceGuardedExpressionGroup(int length) {
488 GuardedExpression[] expressions = new GuardedExpression[length];
489 for(int i=0;i<expressions.length;++i) {
490 expressions[i] = (GuardedExpression)get(i);
492 return new GuardedExpressionGroup(expressions);
496 protected Object reduceGuardedRhs() {
497 int length = length();
498 if(length > 2 && get(length-2) instanceof Token) {
499 EBlock block = (EBlock)get(length-1);
500 block.addStatement(new GuardStatement(reduceGuardedExpressionGroup(length-2)));
501 block.location = Locations.NO_LOCATION;
505 return reduceGuardedExpressionGroup(length);
509 protected Object reduceStatements() {
510 EBlock block = new EBlock();
512 for(int i=1;i<length();i+=2)
513 block.addStatement((Statement)get(i));
518 protected Object reduceConstructor() {
520 for(idPos=0;idPos<length();idPos+=2)
521 if(((Token)get(idPos)).id == SCLTerminals.ID)
523 DAnnotationAst[] annotations = idPos == 0 ? DAnnotationAst.EMPTY_ARRAY : new DAnnotationAst[idPos/2];
524 for(int i=0;i<idPos/2;++i)
525 annotations[i] = new DAnnotationAst((Token)get(i*2),
526 Arrays.asList((Expression)get(i*2+1)));
527 TypeAst[] parameters = new TypeAst[length()-idPos-1];
528 for(int i=0;i<parameters.length;++i)
529 parameters[i] = (TypeAst)get(i+idPos+1);
530 return new ConstructorAst(annotations, (Token)get(idPos), parameters, null);
534 protected Object reduceContext() {
535 ArrayList<TypeAst> result = new ArrayList<TypeAst>(length()/2-1);
536 for(int i=1;i<length()-2;i+=2)
537 result.add((TypeAst)get(i));
542 protected Object reduceTypeVar() {
543 return new TVarAst(((Token)get(0)).text);
547 protected Object reduceTupleType() {
549 return new TTupleAst(TypeAst.EMPTY_ARRAY);
551 Symbol sym = (Symbol)get(1);
552 sym.location = Locations.NO_LOCATION;
555 int dim = length()/2;
556 TypeAst[] parameters = new TypeAst[dim];
557 for(int i=0;i<dim;++i)
558 parameters[i] = (TypeAst)get(i*2+1);
559 return new TTupleAst(parameters);
563 protected Object reduceListType() {
564 return new TListAst((TypeAst)get(1));
568 protected Object reduceListTypeConstructor() {
569 return new TVarAst("[]");
573 protected Object reduceTupleConstructor() {
574 return new EVar(Types.tupleConstructor(length()-1).name);
578 protected Object reduceVar() {
583 protected Object reduceBlank() {
584 return new EVar(((Token)get(0)).location, "_");
588 protected Object reduceInteger() {
589 return new EIntegerLiteral(((Token)get(0)).text);
593 protected Object reduceFloat() {
594 return new ERealLiteral(((Token)get(0)).text);
598 protected Object reduceString() {
603 protected Object reduceChar() {
604 String text = ((Token)get(0)).text;
605 char c = text.charAt(text.length()-2);
606 if(text.length() == 4) {
608 case 'n': c = '\n'; break;
609 case 't': c = '\t'; break;
610 case 'b': c = '\b'; break;
611 case 'f': c = '\f'; break;
612 case 'r': c = '\r'; break;
615 return new ELiteral(new CharacterConstant(c));
619 protected Object reduceTuple() {
621 return new EConstant(Builtins.TUPLE_CONSTRUCTORS[0]);
623 Symbol sym = (Symbol)get(1);
624 sym.location = Locations.NO_LOCATION;
627 int dim = length()/2;
628 Expression[] parameters = new Expression[dim];
629 for(int i=0;i<dim;++i)
630 parameters[i] = (Expression)get(i*2+1);
631 EConstant tupleConstructor = new EConstant(Builtins.TUPLE_CONSTRUCTORS[dim]);
632 tupleConstructor.location = Locations.location(
633 Locations.beginOf(((Token)get(0)).location),
634 Locations.endOf(((Token)get(length()-1)).location));
635 return new EApply(tupleConstructor, parameters);
638 public static Expression rightSection(EVar op, Expression e) {
639 long loc = Locations.combine(op.location, e.location);
640 Variable var = new Variable("rightSectionTemp");
641 return new ESimpleLambda(loc, var,
642 new EApply(loc, op, new EVariable(loc, var), e));
646 protected Object reduceRightSection() {
647 Variable var = new Variable("rightSectionTemp");
648 long loc = Locations.combine(((Token)get(0)).location, ((Token)get(length()-1)).location);
649 EVar symbol = (EVar)get(1);
650 return new ESimpleLambda(var,
651 new EApply(loc, symbol,
652 new EVariable(loc, var), (Expression)get(2)));
656 protected Object reduceLeftSection() {
657 return new EApply((EVar)get(2), (Expression)get(1));
661 protected Object reduceListLiteral() {
663 return new EListLiteral(Expression.EMPTY_ARRAY);
664 int dim = length()/2;
665 Expression[] components = new Expression[dim];
666 for(int i=0;i<dim;++i)
667 components[i] = (Expression)get(i*2+1);
668 return new EListLiteral(components);
672 protected Object reduceRange() {
680 protected Object reduceListComprehension() {
681 ListQualifier qualifier = (ListQualifier)get(3);
682 for(int i=5;i<length();i+=2) {
683 ListQualifier right = (ListQualifier)get(i);
684 if(right instanceof ListThen) {
685 ((ListThen) right).setLeft(qualifier);
689 qualifier = new ListSeq(qualifier, right);
691 return new EListComprehension((Expression)get(1), qualifier);
695 protected Object reduceAs() {
696 Token id = (Token)get(0);
697 return new EAsPattern(new EVar(id.location, id.text), (Expression)get(2));
701 protected Object reduceGuardedExpEq() {
702 Expression[] guards = new Expression[length()/2-1];
703 for(int i=0;i<guards.length;++i)
704 guards[i] = (Expression)get(i*2+1);
705 return new GuardedExpression(guards, (Expression)get(length()-1));
709 protected Object reduceLambda() {
710 Expression[] patterns = new Expression[length()-3];
711 for(int i=0;i<patterns.length;++i)
712 patterns[i] = (Expression)get(i+1);
713 Case case_ = new Case(patterns, (Expression)get(length()-1));
714 case_.setLhs(Locations.combine(patterns[0].location, patterns[patterns.length-1].location));
715 return new ELambda(case_);
719 protected Object reduceLambdaMatch() {
720 Case[] cases = new Case[length()/2-1];
721 for(int i=0;i<cases.length;++i)
722 cases[i] = (Case)get(i*2+2);
723 return new ELambda(cases);
727 protected Object reduceLet() {
728 EBlock block = (EBlock)get(1);
729 Expression expression = (Expression)get(3);
730 block.addStatement(new GuardStatement(expression));
731 Token letToken = (Token)get(0);
732 block.location = Locations.location(
733 Locations.beginOf(letToken.location),
734 Locations.endOf(expression.location));
739 protected Object reduceIf() {
743 length() == 6 ? (Expression)get(5) : null);
747 protected Object reduceMatch() {
748 Case[] cases = new Case[length()/2-2];
749 for(int i=0;i<cases.length;++i)
750 cases[i] = (Case)get(i*2+4);
751 return new EMatch((Expression)get(1), cases);
755 protected Object reduceDo() {
756 EBlock block = (EBlock)get(1);
757 Token doToken = (Token)get(0);
758 block.setMonadic( doToken.text.equals("mdo") );
759 block.location = Locations.location(Locations.beginOf(doToken.location), Locations.endOf(block.location));
764 protected Object reduceSelect() {
765 return new ESelect(((Token)get(0)).id, (Expression)get(1), new QConjunction((Query[])get(3)));
769 protected Object reduceEnforce() {
770 return new EEnforce(new QConjunction((Query[])get(1)));
774 protected Object reduceApply() {
777 Expression[] parameters = new Expression[length()-1];
778 for(int i=0;i<parameters.length;++i)
779 parameters[i] = (Expression)get(i+1);
780 return new EApply((Expression)get(0), parameters);
784 protected Object reduceSymbol() {
785 return new EVar(((Token)get(0)).text);
789 protected Object reduceEscapedId() {
790 return new EVar(((Token)get(0)).text);
794 protected Object reduceMinus() {
795 return new EVar(((Token)get(0)).text);
799 protected Object reduceLess() {
800 return new EVar(((Token)get(0)).text);
804 protected Object reduceGreater() {
805 return new EVar(((Token)get(0)).text);
809 protected Object reduceDot() {
810 return new EVar(((Token)get(0)).text);
814 protected Object reduceCase() {
815 return new Case((Expression)get(0), (Expression)get(1));
819 protected Object reduceGuardQualifier() {
820 return new ListGuard((Expression)get(0));
824 protected Object reduceLetQualifier() {
825 return new ListAssignment((Expression)get(0), (Expression)get(2));
829 protected Object reduceBindQualifier() {
830 return new ListGenerator((Expression)get(0), (Expression)get(2));
834 protected Object reduceThenQualifier() {
835 return new ListThen((Expression)get(1), length()==4 ? (Expression)get(3) : null);
839 protected Object reduceGuardStatement() {
840 return new GuardStatement((Expression)get(0));
844 protected Object reduceLetStatement() {
845 return new LetStatement((Expression)get(0), (Expression)get(1));
849 protected Object reduceBindStatement() {
850 return new BindStatement((Expression)get(0), (Expression)get(2));
854 protected Object reduceSimpleCaseRhs() {
859 protected Object reduceGuardedCaseRhs() {
860 GuardedExpression[] expressions = new GuardedExpression[length()];
861 for(int i=0;i<expressions.length;++i)
862 expressions[i] = (GuardedExpression)get(i);
863 return new GuardedExpressionGroup(expressions);
867 protected Object reduceGuardedExpArrow() {
868 Expression[] guards = new Expression[length()/2-1];
869 for(int i=0;i<guards.length;++i)
870 guards[i] = (Expression)get(i*2+1);
871 return new GuardedExpression(guards, (Expression)get(length()-1));
875 protected Object reduceEffect() {
876 ArrayList<TypeAst> effects = new ArrayList<TypeAst>(length()/2-1);
877 for(int i=1;i<length()-1;i+=2) {
878 Token token = (Token)get(i);
879 TVarAst ast = new TVarAst(token.text);
880 ast.location = token.location;
883 return new TEffectAst(effects, (TypeAst)get(length()-1));
887 protected Object reduceJustEtype() {
892 protected Object reduceForAll() {
893 String[] vars = new String[length()-3];
894 for(int i=0;i<vars.length;++i)
895 vars[i] = ((Token)get(i+1)).text;
896 return new TForAllAst(vars, (TypeAst)get(length()-1));
900 protected Object reduceApplyType() {
901 TypeAst[] parameters = new TypeAst[length()-1];
902 for(int i=0;i<parameters.length;++i)
903 parameters[i] = (TypeAst)get(i+1);
904 return new TApplyAst((TypeAst)get(0), parameters);
907 @SuppressWarnings("unchecked")
909 protected void postReduce(Object reduced) {
910 if(!(reduced instanceof Symbol))
912 Symbol sym = (Symbol)reduced;
913 if(sym.location != Locations.NO_LOCATION || length() == 0)
915 Object first = get(0);
916 if(!(first instanceof Symbol)) {
917 if(first instanceof List) {
918 List<Object> ll = (List<Object>)first;
922 Object[] ll = (Object[])first;
929 Object last = get(length()-1);
930 if(!(last instanceof Symbol)) {
931 if(last instanceof List) {
932 List<Object> ll = (List<Object>)last;
933 last = ll.get(ll.size()-1);
936 Object[] ll = (Object[])last;
938 last = ll[ll.length-1];
940 last = get(length()-2);
943 sym.location = (((Symbol)first).location & 0xffffffff00000000L)
944 | (((Symbol)last).location & 0xffffffffL);
945 /*for(int i=0;i<length();++i) {
947 System.out.print(obj.getClass().getSimpleName());
948 if(obj instanceof Token) {
949 Token t = (Token)obj;
950 System.out.print("(" + t.text + ")");
952 if(obj instanceof Symbol) {
953 Symbol s = (Symbol)obj;
954 System.out.print("["+ Locations.beginOf(s.location) + "-" + Locations.endOf(s.location) + "]");
956 System.out.print(" ");
958 System.out.println("-> " + reduced.getClass().getSimpleName() + " " +
959 Locations.beginOf(sym.location) + "-" + Locations.endOf(sym.location));*/
963 protected RuntimeException syntaxError(Token token, String description) {
964 throw new SCLSyntaxErrorException(token.location, description);
968 protected Object reduceIdAccessor() {
969 return new IdAccessor('.', ((Token)get(0)).text);
973 protected Object reduceStringAccessor() {
974 return new StringAccessor('.', ((Token)get(1)).text);
978 protected Object reduceExpAccessor() {
979 return new ExpressionAccessor('.', (Expression)get(1));
983 protected Object reduceFieldAccess() {
986 Expression result = (Expression)get(0);
987 for(int i=2;i<length();i+=2) {
988 FieldAccessor accessor = (FieldAccessor)get(i);
989 accessor.accessSeparator = ((Token)get(i-1)).text.charAt(0);
990 result = new EFieldAccess(result, accessor);
996 protected Object reduceQueryBlock() {
998 return Query.EMPTY_ARRAY;
999 Query[] queries = new Query[length()/2];
1000 for(int i=0;i<queries.length;++i)
1001 queries[i] = (Query)get(2*i+1);
1006 protected Object reduceGuardQuery() {
1007 return new QPreGuard((Expression)get(0));
1011 protected Object reduceEqualsQuery() {
1012 return new QPreEquals((Expression)get(0), (Expression)get(2));
1016 protected Object reduceBindQuery() {
1017 return new QPreBinds((Expression)get(0), (Expression)get(2));
1021 protected Object reduceCompositeQuery() {
1022 Query[] queries = (Query[])get(1);
1023 switch(((Token)get(0)).text.charAt(1)) {
1024 case '&': return new QConjunction(queries);
1025 case '|': return new QDisjunction(queries);
1026 case '!': return new QNegation(new QConjunction(queries));
1027 case '?': return new QAlternative(queries);
1028 default: throw new InternalCompilerError();
1033 protected Object reduceRuleStatement() {
1034 return new RuleStatement((Expression)get(0), new QConjunction((Query[])get(2)));
1038 protected Object reduceHashedId() {
1039 return new EVar("#" + ((Token)get(1)).text);
1043 protected Object reduceStringLiteral() {
1044 int expCount = length()/3;
1046 return new ELiteral(new StringConstant(((Token)get(1)).text));
1048 String[] strings = new String[expCount+1];
1049 Expression[] expressions = new Expression[expCount];
1050 for(int i=0;i<expCount;++i) {
1051 strings[i] = ((Token)get(i*3+1)).text;
1052 expressions[i] = (Expression)get(i*3+2);
1054 strings[expCount] = ((Token)get(expCount*3+1)).text;
1055 return new EStringLiteral(strings, expressions);
1060 protected Object reduceOneCommand() {
1065 protected Object reduceManyCommands() {
1070 protected Object reduceStatementCommand() {
1071 // to be extended in subclasses
1076 protected Object reduceImportCommand() {
1077 // to be extended in subclasses
1082 protected Object reduceImportValueItem() {
1083 return new EVar(((Token)get(0)).text);
1087 protected Object reduceImportHiding() {
1088 EVar[] values = new EVar[(length()-2)/2];
1089 for(int i=0;i<values.length;++i)
1090 values[i] = (EVar)get(i*2+2);
1091 return new ImportDeclaration.ImportSpec(true, values);
1095 protected Object reduceImportShowing() {
1096 EVar[] values = new EVar[(length()-1)/2];
1097 for(int i=0;i<values.length;++i)
1098 values[i] = (EVar)get(i*2+1);
1099 return new ImportDeclaration.ImportSpec(false, values);
1103 protected Object reduceRuleDeclarations() {
1104 ArrayList<Object> declarations = new ArrayList<Object>(length()/2);
1105 for(int i=1;i<length();i+=2)
1106 declarations.add((Object)get(i));
1107 return declarations;
1110 private static final String[] EMPTY_STRING_ARRAY = new String[0];
1112 @SuppressWarnings("unchecked")
1114 protected Object reduceRuleDefinition() {
1115 String[] extendsNames = EMPTY_STRING_ARRAY;
1117 int extendsCount = (length() - 4) / 2;
1118 extendsNames = new String[extendsCount];
1119 for(int i=0;i<extendsCount;++i)
1120 extendsNames[i] = ((Token)get(3+i*2)).text;
1123 DRuleAst rule = new DRuleAst(
1124 ((Token)get(0)).id == SCLTerminals.ABSTRACT_RULE,
1125 ((Token)get(1)).text,
1128 ArrayList<Object> ruleDeclarations = (ArrayList<Object>)get(length()-1);
1129 ArrayList<Query> section = null;
1130 for(Object decl : ruleDeclarations) {
1131 if(decl instanceof DAnnotationAst) {
1132 DAnnotationAst annotation = (DAnnotationAst)decl;
1133 section = rule.getSection(annotation.id.text.substring(1));
1135 else if(decl instanceof Query) {
1137 section = rule.getSection("when");
1138 section.add((Query)decl);
1141 throw new InternalCompilerError();
1147 protected Object reduceQueryRuleDeclaration() {
1152 protected Object reduceMappingRelationDefinition() {
1153 TypeAst[] types = new TypeAst[length()-2];
1154 for(int i=0;i<types.length;++i)
1155 types[i] = (TypeAst)get(i+2);
1156 return new DMappingRelationAst(
1157 ((Token)get(1)).text,
1162 protected Object reduceTransformation() {
1163 return new ETransformation(
1164 ((Token)get(1)).text,
1165 new QConjunction((Query[])get(3))
1169 @SuppressWarnings("unchecked")
1171 protected Object reduceRelationDefinition() {
1172 return new DRelationAst((Expression)get(0),
1173 ((ArrayList<Object>)get(2)).toArray());
1177 protected Object reduceRecord() {
1178 FieldAssignment[] fields = new FieldAssignment[length()/2-1];
1179 for(int i=0;i<fields.length;++i)
1180 fields[i] = (FieldAssignment)get(2+i*2);
1181 return new ERecord(new EVar((Token)get(0)), fields);
1185 protected Object reduceField() {
1186 return new FieldAssignment(((Token)get(0)).text, (Expression)get(2));
1190 protected Object reduceFieldShorthand() {
1191 return new FieldAssignment(((Token)get(0)).text, null);
1195 protected Object reduceRecordConstructor() {
1197 for(idPos=0;idPos<length();idPos+=2)
1198 if(((Token)get(idPos)).id == SCLTerminals.ID)
1200 DAnnotationAst[] annotations = idPos == 0 ? DAnnotationAst.EMPTY_ARRAY : new DAnnotationAst[idPos/2];
1201 for(int i=0;i<idPos/2;++i)
1202 annotations[i] = new DAnnotationAst((Token)get(i*2),
1203 Arrays.asList((Expression)get(i*2+1)));
1204 TypeAst[] parameters = new TypeAst[(length()-idPos-1)/2];
1205 String[] fieldNames = new String[parameters.length];
1206 for(int i=0;i<parameters.length;++i) {
1207 FieldDescription fieldDesc = (FieldDescription)get(idPos+(i+1)*2);
1208 parameters[i] = fieldDesc.type;
1209 fieldNames[i] = fieldDesc.name;
1211 return new ConstructorAst(annotations, (Token)get(idPos), parameters, fieldNames);
1215 protected Object reduceFieldDescription() {
1216 return new FieldDescription(((Token)get(0)).text, (TypeAst)get(2));
1220 protected Object reduceEq() {
1221 return (Expression)get(2);
1225 protected Object reduceEquationBlock() {
1227 return new EEquations(Equation.EMPTY_ARRAY);
1228 Equation[] equations = new Equation[length()/2+1];
1229 for(int i=0;i<equations.length;++i)
1230 equations[i] = (Equation)get(2*i);
1231 return new EEquations(equations);
1235 protected Object reduceGuardEquation() {
1236 return new EqGuard((Expression)get(0));
1240 protected Object reduceBasicEquation() {
1241 return new EqBasic((Expression)get(0), (Expression)get(2));
1245 protected Object reduceViewPattern() {
1246 return new EViewPattern((Expression)get(1), (Expression)get(3));
1250 protected Object reduceCHRStatement() {
1251 return new CHRStatement((ListQualifier[])get(0), (ListQualifier[])get(2));
1255 protected Object reduceConstraintStatement() {
1256 ConstructorAst constructor = (ConstructorAst)get(1);
1257 return new ConstraintStatement(constructor.name, constructor.parameters, constructor.fieldNames, constructor.annotations);
1261 protected Object reduceCHRQuery() {
1262 ListQualifier[] query = new ListQualifier[(length()+1)/2];
1263 for(int i=0;i<query.length;++i)
1264 query[i] = (ListQualifier)get(i*2);
1270 protected Object reduceWhen() {
1272 new QConjunction((Query[])get(1)),
1273 (Expression)get(3));
1277 protected Object reduceVerboseCHRQuery() {
1278 ListQualifier[] query = new ListQualifier[(length()-1)/2];
1279 for(int i=0;i<query.length;++i)
1280 query[i] = (ListQualifier)get(i*2+1);
1285 protected Object reduceVerboseCHRStatement() {
1286 return new CHRStatement((ListQualifier[])get(1), (ListQualifier[])get(3));
1290 protected Object reduceDummy() {
1291 throw new UnsupportedOperationException();
1295 protected Object reduceRulesetDefinition() {
1296 Token name = (Token)get(1);
1297 EBlock block = (EBlock)get(3);
1298 return new DRulesetAst(name.text, block);
1302 protected Object reduceLocalInclude() {
1303 Token name = (Token)get(1);
1304 Expression value = (Expression)get(2);
1305 return new IncludeStatement(name, value);
1309 protected Object reduceConstraintSpec() {
1310 Expression[] expressions = new Expression[length()/2-1];
1311 for(int i=0;i<expressions.length;++i)
1312 expressions[i] = (Expression)get(2*i+1);