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.constants.CharacterConstant;
12 import org.simantics.scl.compiler.constants.StringConstant;
13 import org.simantics.scl.compiler.elaboration.equation.EqBasic;
14 import org.simantics.scl.compiler.elaboration.equation.EqGuard;
15 import org.simantics.scl.compiler.elaboration.equation.Equation;
16 import org.simantics.scl.compiler.elaboration.expressions.Case;
17 import org.simantics.scl.compiler.elaboration.expressions.EApply;
18 import org.simantics.scl.compiler.elaboration.expressions.EAsPattern;
19 import org.simantics.scl.compiler.elaboration.expressions.EBinary;
20 import org.simantics.scl.compiler.elaboration.expressions.EBinaryRightSide;
21 import org.simantics.scl.compiler.elaboration.expressions.EBlock;
22 import org.simantics.scl.compiler.elaboration.expressions.EConstant;
23 import org.simantics.scl.compiler.elaboration.expressions.EEnforce;
24 import org.simantics.scl.compiler.elaboration.expressions.EEntityTypeAnnotation;
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.LetStatement;
58 import org.simantics.scl.compiler.elaboration.expressions.block.RuleStatement;
59 import org.simantics.scl.compiler.elaboration.expressions.block.Statement;
60 import org.simantics.scl.compiler.elaboration.expressions.list.ListAssignment;
61 import org.simantics.scl.compiler.elaboration.expressions.list.ListGenerator;
62 import org.simantics.scl.compiler.elaboration.expressions.list.ListGuard;
63 import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifier;
64 import org.simantics.scl.compiler.elaboration.expressions.list.ListSeq;
65 import org.simantics.scl.compiler.elaboration.expressions.list.ListThen;
66 import org.simantics.scl.compiler.elaboration.expressions.records.FieldAssignment;
67 import org.simantics.scl.compiler.elaboration.java.Builtins;
68 import org.simantics.scl.compiler.elaboration.query.QAlternative;
69 import org.simantics.scl.compiler.elaboration.query.QConjunction;
70 import org.simantics.scl.compiler.elaboration.query.QDisjunction;
71 import org.simantics.scl.compiler.elaboration.query.QNegation;
72 import org.simantics.scl.compiler.elaboration.query.Query;
73 import org.simantics.scl.compiler.elaboration.query.pre.QPreBinds;
74 import org.simantics.scl.compiler.elaboration.query.pre.QPreEquals;
75 import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard;
76 import org.simantics.scl.compiler.errors.Locations;
77 import org.simantics.scl.compiler.internal.parsing.Symbol;
78 import org.simantics.scl.compiler.internal.parsing.Token;
79 import org.simantics.scl.compiler.internal.parsing.declarations.ConstructorAst;
80 import org.simantics.scl.compiler.internal.parsing.declarations.DAnnotationAst;
81 import org.simantics.scl.compiler.internal.parsing.declarations.DClassAst;
82 import org.simantics.scl.compiler.internal.parsing.declarations.DDataAst;
83 import org.simantics.scl.compiler.internal.parsing.declarations.DDerivingInstanceAst;
84 import org.simantics.scl.compiler.internal.parsing.declarations.DDocumentationAst;
85 import org.simantics.scl.compiler.internal.parsing.declarations.DEffectAst;
86 import org.simantics.scl.compiler.internal.parsing.declarations.DFixityAst;
87 import org.simantics.scl.compiler.internal.parsing.declarations.DImportJavaAst;
88 import org.simantics.scl.compiler.internal.parsing.declarations.DInstanceAst;
89 import org.simantics.scl.compiler.internal.parsing.declarations.DMappingRelationAst;
90 import org.simantics.scl.compiler.internal.parsing.declarations.DModuleHeader;
91 import org.simantics.scl.compiler.internal.parsing.declarations.DRelationAst;
92 import org.simantics.scl.compiler.internal.parsing.declarations.DRuleAst;
93 import org.simantics.scl.compiler.internal.parsing.declarations.DTypeAst;
94 import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst;
95 import org.simantics.scl.compiler.internal.parsing.declarations.DValueTypeAst;
96 import org.simantics.scl.compiler.internal.parsing.declarations.DeclarationAst;
97 import org.simantics.scl.compiler.internal.parsing.declarations.FieldDescription;
98 import org.simantics.scl.compiler.internal.parsing.declarations.FundepAst;
99 import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
100 import org.simantics.scl.compiler.internal.parsing.types.TApplyAst;
101 import org.simantics.scl.compiler.internal.parsing.types.TEffectAst;
102 import org.simantics.scl.compiler.internal.parsing.types.TForAllAst;
103 import org.simantics.scl.compiler.internal.parsing.types.TFunctionAst;
104 import org.simantics.scl.compiler.internal.parsing.types.TListAst;
105 import org.simantics.scl.compiler.internal.parsing.types.TPredAst;
106 import org.simantics.scl.compiler.internal.parsing.types.TTupleAst;
107 import org.simantics.scl.compiler.internal.parsing.types.TVarAst;
108 import org.simantics.scl.compiler.internal.parsing.types.TypeAst;
109 import org.simantics.scl.compiler.module.ImportDeclaration;
110 import org.simantics.scl.compiler.types.Types;
113 public class SCLParserImpl extends SCLParser {
115 private final SCLPostLexer lexer;
116 private SCLParserOptions options;
118 public SCLParserImpl(Reader reader) {
119 lexer = new SCLPostLexer(reader);
122 public void setParserOptions(SCLParserOptions options) {
123 this.options = options;
124 lexer.setParserOptions(options);
127 public boolean isEmpty() throws Exception {
128 return lexer.peekToken().id == SCLTerminals.EOF;
132 protected Token nextToken() {
134 Token token = lexer.nextToken();
135 /*System.out.println("TOKEN " + token.text + " (" + TERMINAL_NAMES[token.id] + ")" +
137 + Locations.beginOf(token.location) + ".."
138 + Locations.endOf(token.location) + "]");*/
140 } catch(Exception e) {
141 if(e instanceof RuntimeException)
142 throw (RuntimeException)e;
144 throw new RuntimeException(e);
149 protected Object reduceDeclarations() {
150 ArrayList<DeclarationAst> declarations = new ArrayList<DeclarationAst>(length()/2);
151 for(int i=1;i<length();i+=2)
152 declarations.add((DeclarationAst)get(i));
157 protected Object reduceModule() {
158 ArrayList<DeclarationAst> declarations = new ArrayList<DeclarationAst>(length()/2+1);
159 for(int i=0;i<length();i+=2) {
160 DeclarationAst declaration = (DeclarationAst)get(i);
161 if(declaration == null)
162 throw new NullPointerException();
163 declarations.add(declaration);
169 protected Object reduceModuleHeader() {
170 FieldAssignment[] fields = new FieldAssignment[length()/2-1];
171 for(int i=0;i<fields.length;++i)
172 fields[i] = (FieldAssignment)get(2+i*2);
173 return new DModuleHeader(fields);
177 protected Object reduceLocalTypeAnnotation() {
180 return new ETypeAnnotation((Expression)get(0), (TypeAst)get(2));
184 protected Object reduceTypeAnnotation() {
185 EVar[] names = new EVar[length()/2];
186 for(int i=0;i<names.length;++i)
187 names[i] = (EVar)get(i*2);
188 return new DValueTypeAst(
190 (TypeAst)get(length()-1)
195 protected Object reduceValueDefinition() {
196 Expression rhs = (Expression)get(1);
197 return new DValueAst((Expression)get(0), rhs);
201 protected Object reduceDataDefinition() {
203 ArrayList<String> parameters = new ArrayList<String>();
204 while(i < length()) {
205 Token token = (Token)get(i++);
206 if(token.id != SCLTerminals.ID)
208 parameters.add(token.text);
210 ArrayList<ConstructorAst> constructors = new ArrayList<ConstructorAst>();
211 for(;i < length();i+=2)
212 constructors.add((ConstructorAst)get(i));
214 ((Token)get(1)).text,
215 parameters.toArray(new String[parameters.size()]),
216 constructors.toArray(new ConstructorAst[constructors.size()]),
222 protected Object reduceTypeDefinition() {
224 ArrayList<String> parameters = new ArrayList<String>();
226 Token token = (Token)get(i++);
227 if(token.id != SCLTerminals.ID)
229 parameters.add(token.text);
232 ((Token)get(1)).text,
233 parameters.toArray(new String[parameters.size()]),
238 @SuppressWarnings("unchecked")
240 protected Object reduceClassDefinition() {
242 ArrayList<TypeAst> context;
243 if(get(i) instanceof Token)
244 context = new ArrayList<TypeAst>(0);
246 context = (ArrayList<TypeAst>)get(i++);
247 String name = ((Token)get(i++)).text;
248 ArrayList<String> parameters = new ArrayList<String>();
249 while(i < length()) {
250 Token token = (Token)get(i);
251 if(token.id != SCLTerminals.ID)
253 parameters.add(token.text);
256 ArrayList<DeclarationAst> declarations = null;
257 FundepAst[] fundeps = FundepAst.EMPTY_ARRAY;
258 while(i < length()) {
259 Token token = (Token)get(i++);
260 if(token.id == SCLTerminals.WHERE) {
261 declarations = (ArrayList<DeclarationAst>)get(i++);
263 else if(token.id == SCLTerminals.BAR) {
264 fundeps = (FundepAst[])get(i++);
267 throw new InternalCompilerError();
269 return new DClassAst(context, name,
270 parameters.toArray(new String[parameters.size()]),
276 protected Object reduceFundep() {
277 String[] from = new String[length()-2];
278 for(int i=0;i<from.length;++i)
279 from[i] = ((Token)get(i)).text;
280 String to = ((Token)get(length()-1)).text;
281 return new FundepAst(from, to);
285 protected Object reduceFundeps() {
286 FundepAst[] fundeps = new FundepAst[(length()+1)/2];
287 for(int i=0;i<fundeps.length;++i)
288 fundeps[i] = (FundepAst)get(i*2);
292 @SuppressWarnings("unchecked")
294 protected Object reduceInstanceDefinition() {
296 ArrayList<TypeAst> context;
297 if(get(i) instanceof Token)
298 context = new ArrayList<TypeAst>(0);
300 context = (ArrayList<TypeAst>)get(i++);
301 Token nameToken = (Token)get(i++);
302 EVar name = new EVar(nameToken.location, nameToken.text);
303 ArrayList<TypeAst> parameters = new ArrayList<TypeAst>();
304 while(i < length()) {
305 Object symbol = get(i++);
306 if(symbol instanceof Token)
308 parameters.add((TypeAst)symbol);
310 ArrayList<DeclarationAst> declarations = null;
312 declarations = (ArrayList<DeclarationAst>)get(i);
313 return new DInstanceAst(context, name,
314 parameters.toArray(new TypeAst[parameters.size()]),
318 @SuppressWarnings("unchecked")
320 protected Object reduceDerivingInstanceDefinition() {
322 ArrayList<TypeAst> context;
323 if(get(i) instanceof Token)
324 context = new ArrayList<TypeAst>(0);
326 context = (ArrayList<TypeAst>)get(i++);
327 Token nameToken = (Token)get(i++);
328 EVar name = new EVar(nameToken.location, nameToken.text);
329 ArrayList<TypeAst> parameters = new ArrayList<TypeAst>();
330 while(i < length()) {
331 Object symbol = get(i++);
332 parameters.add((TypeAst)symbol);
334 return new DDerivingInstanceAst(context, name,
335 parameters.toArray(new TypeAst[parameters.size()]));
339 protected Object reduceDocumentationString() {
340 return new DDocumentationAst(((Token)get(1)).text);
344 protected Object reduceAnnotation() {
345 ArrayList<Expression> parameters = new ArrayList<Expression>(length()-1);
346 for(int i=1;i<length();++i)
347 parameters.add((Expression)get(i));
348 return new DAnnotationAst((Token)get(0), parameters);
352 protected Object reducePrecedenceDefinition() {
353 EVar[] symbols = new EVar[length()/2];
354 for(int i=0;i<symbols.length;++i)
355 symbols[i] = (EVar)get(2*i + 2);
356 Associativity associativity;
357 Token token = (Token)get(0);
358 if(token.text.equals("infixl"))
359 associativity = Associativity.LEFT;
360 else if(token.text.equals("infixr"))
361 associativity = Associativity.RIGHT;
363 associativity = Associativity.NONASSOC;
364 return new DFixityAst(
366 Integer.parseInt(((Token)get(1)).text),
372 protected Object reduceImport() {
373 // (AS ID)? importSpec?
375 String importKeyword = ((Token)get(pos++)).text; // (IMPORT | INCLUDE)
376 ++pos; // BEGIN_STRING
377 String moduleName = ((Token)get(pos++)).text; // END_STRING
378 String localName = "";
380 Object temp = get(pos);
381 if(temp instanceof Token) {
382 Token token = (Token)temp;
383 if(token.id == SCLTerminals.AS) {
385 localName = ((Token)get(pos++)).text; // ID
389 ImportDeclaration.ImportSpec spec = ImportDeclaration.DEFAULT_SPEC;
391 spec = (ImportDeclaration.ImportSpec)get(pos++);
392 return new ImportDeclaration(moduleName, localName,
393 importKeyword.equals("include"),
398 protected Object reduceJustImport() {
402 @SuppressWarnings("unchecked")
404 protected Object reduceImportJava() {
405 return new DImportJavaAst(((Token)get(2)).text, (ArrayList<DeclarationAst>)get(4));
409 protected Object reduceEffectDefinition() {
410 return new DEffectAst(
411 ((Token)get(1)).text,
412 ((Token)get(3)).text,
413 ((Token)get(5)).text);
417 protected Object reduceVarId() {
418 return new EVar(((Token)get(0)).text);
422 protected Object reduceEscapedSymbol() {
423 return new EVar(((Token)get(0)).text);
427 protected Object reduceTupleTypeConstructor() {
428 return new TVarAst(Types.tupleConstructor(length()-1).name);
432 protected Object reduceArrow() {
434 TypeAst result = (TypeAst)get(i);
437 if( ((Token)get(i+1)).text.equals("=>") )
438 result = new TPredAst((TypeAst)get(i), result);
440 result = new TFunctionAst((TypeAst)get(i), result);
447 protected Object reduceBinary() {
451 EVar negation = null;
452 if(get(i) instanceof Token) {
453 Token token = (Token)get(i++);
454 negation = new EVar(token.location, token.text);
456 EBinary binary = new EBinary((Expression)get(i++), negation);
457 while(i < length()) {
458 EVar operator = (EVar)get(i++);
459 Expression right = (Expression)get(i++);
460 binary.rights.add(new EBinaryRightSide(operator, right));
466 protected Object reduceSimpleRhs() {
470 EBlock block = (EBlock)get(3);
471 Expression expression = (Expression)get(1);
472 block.addStatement(new GuardStatement(expression));
473 block.location = Locations.location(Locations.beginOf(expression.location), Locations.endOf(block.location));
478 private GuardedExpressionGroup reduceGuardedExpressionGroup(int length) {
479 GuardedExpression[] expressions = new GuardedExpression[length];
480 for(int i=0;i<expressions.length;++i) {
481 expressions[i] = (GuardedExpression)get(i);
483 return new GuardedExpressionGroup(expressions);
487 protected Object reduceGuardedRhs() {
488 int length = length();
489 if(length > 2 && get(length-2) instanceof Token) {
490 EBlock block = (EBlock)get(length-1);
491 block.addStatement(new GuardStatement(reduceGuardedExpressionGroup(length-2)));
492 block.location = Locations.NO_LOCATION;
496 return reduceGuardedExpressionGroup(length);
500 protected Object reduceStatements() {
501 EBlock block = new EBlock();
503 for(int i=1;i<length();i+=2)
504 block.addStatement((Statement)get(i));
509 protected Object reduceConstructor() {
511 for(idPos=0;idPos<length();idPos+=2)
512 if(((Token)get(idPos)).id == SCLTerminals.ID)
514 DAnnotationAst[] annotations = idPos == 0 ? DAnnotationAst.EMPTY_ARRAY : new DAnnotationAst[idPos/2];
515 for(int i=0;i<idPos/2;++i)
516 annotations[i] = new DAnnotationAst((Token)get(i*2),
517 Arrays.asList((Expression)get(i*2+1)));
518 TypeAst[] parameters = new TypeAst[length()-idPos-1];
519 for(int i=0;i<parameters.length;++i)
520 parameters[i] = (TypeAst)get(i+idPos+1);
521 return new ConstructorAst(annotations, ((Token)get(idPos)).text, parameters, null);
525 protected Object reduceContext() {
526 ArrayList<TypeAst> result = new ArrayList<TypeAst>(length()/2-1);
527 for(int i=1;i<length()-2;i+=2)
528 result.add((TypeAst)get(i));
533 protected Object reduceTypeVar() {
534 return new TVarAst(((Token)get(0)).text);
538 protected Object reduceTupleType() {
540 return new TTupleAst(TypeAst.EMPTY_ARRAY);
542 Symbol sym = (Symbol)get(1);
543 sym.location = Locations.NO_LOCATION;
546 int dim = length()/2;
547 TypeAst[] parameters = new TypeAst[dim];
548 for(int i=0;i<dim;++i)
549 parameters[i] = (TypeAst)get(i*2+1);
550 return new TTupleAst(parameters);
554 protected Object reduceListType() {
555 return new TListAst((TypeAst)get(1));
559 protected Object reduceListTypeConstructor() {
560 return new TVarAst("[]");
564 protected Object reduceTupleConstructor() {
565 return new EVar(Types.tupleConstructor(length()-1).name);
569 protected Object reduceVar() {
574 protected Object reduceBlank() {
575 return new EVar("_");
579 protected Object reduceInteger() {
580 return new EIntegerLiteral(((Token)get(0)).text);
584 protected Object reduceFloat() {
585 return new ERealLiteral(((Token)get(0)).text);
589 protected Object reduceString() {
594 protected Object reduceChar() {
595 String text = ((Token)get(0)).text;
596 char c = text.charAt(text.length()-2);
597 if(text.length() == 4) {
599 case 'n': c = '\n'; break;
600 case 't': c = '\t'; break;
601 case 'b': c = '\b'; break;
602 case 'f': c = '\f'; break;
603 case 'r': c = '\r'; break;
606 return new ELiteral(new CharacterConstant(c));
610 protected Object reduceTuple() {
612 return new EConstant(Builtins.TUPLE_CONSTRUCTORS[0]);
614 Symbol sym = (Symbol)get(1);
615 sym.location = Locations.NO_LOCATION;
618 int dim = length()/2;
619 Expression[] parameters = new Expression[dim];
620 for(int i=0;i<dim;++i)
621 parameters[i] = (Expression)get(i*2+1);
622 EConstant tupleConstructor = new EConstant(Builtins.TUPLE_CONSTRUCTORS[dim]);
623 tupleConstructor.location = Locations.location(
624 Locations.beginOf(((Token)get(0)).location),
625 Locations.endOf(((Token)get(length()-1)).location));
626 return new EApply(tupleConstructor, parameters);
629 public static Expression rightSection(EVar op, Expression e) {
630 long loc = Locations.combine(op.location, e.location);
631 Variable var = new Variable("rightSectionTemp");
632 return new ESimpleLambda(loc, var,
633 new EApply(loc, op, new EVariable(loc, var), e));
637 protected Object reduceRightSection() {
638 Variable var = new Variable("rightSectionTemp");
639 long loc = Locations.combine(((Token)get(0)).location, ((Token)get(length()-1)).location);
640 EVar symbol = (EVar)get(1);
641 return new ESimpleLambda(var,
642 new EApply(loc, symbol,
643 new EVariable(loc, var), (Expression)get(2)));
647 protected Object reduceLeftSection() {
648 return new EApply((EVar)get(2), (Expression)get(1));
652 protected Object reduceListLiteral() {
654 return new EListLiteral(Expression.EMPTY_ARRAY);
655 int dim = length()/2;
656 Expression[] components = new Expression[dim];
657 for(int i=0;i<dim;++i)
658 components[i] = (Expression)get(i*2+1);
659 return new EListLiteral(components);
663 protected Object reduceRange() {
671 protected Object reduceListComprehension() {
672 ListQualifier qualifier = (ListQualifier)get(3);
673 for(int i=5;i<length();i+=2) {
674 ListQualifier right = (ListQualifier)get(i);
675 if(right instanceof ListThen) {
676 ((ListThen) right).setLeft(qualifier);
680 qualifier = new ListSeq(qualifier, right);
682 return new EListComprehension((Expression)get(1), qualifier);
686 protected Object reduceAs() {
687 Token id = (Token)get(0);
688 return new EAsPattern(new EVar(id.location, id.text), (Expression)get(2));
692 protected Object reduceGuardedExpEq() {
693 Expression[] guards = new Expression[length()/2-1];
694 for(int i=0;i<guards.length;++i)
695 guards[i] = (Expression)get(i*2+1);
696 return new GuardedExpression(guards, (Expression)get(length()-1));
700 protected Object reduceLambda() {
701 Expression[] patterns = new Expression[length()-3];
702 for(int i=0;i<patterns.length;++i)
703 patterns[i] = (Expression)get(i+1);
704 Case case_ = new Case(patterns, (Expression)get(length()-1));
705 case_.setLhs(Locations.combine(patterns[0].location, patterns[patterns.length-1].location));
706 return new ELambda(case_);
710 protected Object reduceLambdaMatch() {
711 Case[] cases = new Case[length()/2-1];
712 for(int i=0;i<cases.length;++i)
713 cases[i] = (Case)get(i*2+2);
714 return new ELambda(cases);
718 protected Object reduceLet() {
719 EBlock block = (EBlock)get(1);
720 Expression expression = (Expression)get(3);
721 block.addStatement(new GuardStatement(expression));
722 Token letToken = (Token)get(0);
723 block.location = Locations.location(
724 Locations.beginOf(letToken.location),
725 Locations.endOf(expression.location));
730 protected Object reduceIf() {
734 length() == 6 ? (Expression)get(5) : null);
738 protected Object reduceMatch() {
739 Case[] cases = new Case[length()/2-2];
740 for(int i=0;i<cases.length;++i)
741 cases[i] = (Case)get(i*2+4);
742 return new EMatch((Expression)get(1), cases);
746 protected Object reduceDo() {
747 EBlock block = (EBlock)get(1);
748 Token doToken = (Token)get(0);
749 block.setMonadic( doToken.text.equals("mdo") );
750 block.location = Locations.location(Locations.beginOf(doToken.location), Locations.endOf(block.location));
755 protected Object reduceSelect() {
756 return new ESelect(((Token)get(0)).id, (Expression)get(1), new QConjunction((Query[])get(3)));
760 protected Object reduceEnforce() {
761 return new EEnforce(new QConjunction((Query[])get(1)));
765 protected Object reduceApply() {
768 Expression[] parameters = new Expression[length()-1];
769 for(int i=0;i<parameters.length;++i)
770 parameters[i] = (Expression)get(i+1);
771 return new EApply((Expression)get(0), parameters);
775 protected Object reduceSymbol() {
776 return new EVar(((Token)get(0)).text);
780 protected Object reduceEscapedId() {
781 return new EVar(((Token)get(0)).text);
785 protected Object reduceMinus() {
786 return new EVar(((Token)get(0)).text);
790 protected Object reduceLess() {
791 return new EVar(((Token)get(0)).text);
795 protected Object reduceGreater() {
796 return new EVar(((Token)get(0)).text);
800 protected Object reduceDot() {
801 return new EVar(((Token)get(0)).text);
805 protected Object reduceCase() {
806 return new Case((Expression)get(0), (Expression)get(1));
810 protected Object reduceGuardQualifier() {
811 return new ListGuard((Expression)get(0));
815 protected Object reduceLetQualifier() {
816 return new ListAssignment((Expression)get(0), (Expression)get(2));
820 protected Object reduceBindQualifier() {
821 return new ListGenerator((Expression)get(0), (Expression)get(2));
825 protected Object reduceThenQualifier() {
826 return new ListThen((Expression)get(1), length()==4 ? (Expression)get(3) : null);
830 protected Object reduceGuardStatement() {
831 return new GuardStatement((Expression)get(0));
835 protected Object reduceLetStatement() {
836 return new LetStatement((Expression)get(0), (Expression)get(1));
840 protected Object reduceBindStatement() {
841 return new BindStatement((Expression)get(0), (Expression)get(2));
845 protected Object reduceSimpleCaseRhs() {
850 protected Object reduceGuardedCaseRhs() {
851 GuardedExpression[] expressions = new GuardedExpression[length()];
852 for(int i=0;i<expressions.length;++i)
853 expressions[i] = (GuardedExpression)get(i);
854 return new GuardedExpressionGroup(expressions);
858 protected Object reduceGuardedExpArrow() {
859 Expression[] guards = new Expression[length()/2-1];
860 for(int i=0;i<guards.length;++i)
861 guards[i] = (Expression)get(i*2+1);
862 return new GuardedExpression(guards, (Expression)get(length()-1));
866 protected Object reduceEffect() {
867 ArrayList<TypeAst> effects = new ArrayList<TypeAst>(length()/2-1);
868 for(int i=1;i<length()-1;i+=2) {
869 Token token = (Token)get(i);
870 TVarAst ast = new TVarAst(token.text);
871 ast.location = token.location;
874 return new TEffectAst(effects, (TypeAst)get(length()-1));
878 protected Object reduceJustEtype() {
883 protected Object reduceForAll() {
884 String[] vars = new String[length()-3];
885 for(int i=0;i<vars.length;++i)
886 vars[i] = ((Token)get(i+1)).text;
887 return new TForAllAst(vars, (TypeAst)get(length()-1));
891 protected Object reduceApplyType() {
892 TypeAst[] parameters = new TypeAst[length()-1];
893 for(int i=0;i<parameters.length;++i)
894 parameters[i] = (TypeAst)get(i+1);
895 return new TApplyAst((TypeAst)get(0), parameters);
898 @SuppressWarnings("unchecked")
900 protected void postReduce(Object reduced) {
901 if(!(reduced instanceof Symbol))
903 Symbol sym = (Symbol)reduced;
904 if(sym.location != Locations.NO_LOCATION || length() == 0)
906 Object first = get(0);
907 if(!(first instanceof Symbol)) {
908 if(first instanceof List) {
909 List<Object> ll = (List<Object>)first;
913 Object[] ll = (Object[])first;
920 Object last = get(length()-1);
921 if(!(last instanceof Symbol)) {
922 if(last instanceof List) {
923 List<Object> ll = (List<Object>)last;
924 last = ll.get(ll.size()-1);
927 Object[] ll = (Object[])last;
929 last = ll[ll.length-1];
931 last = get(length()-2);
934 sym.location = (((Symbol)first).location & 0xffffffff00000000L)
935 | (((Symbol)last).location & 0xffffffffL);
936 /*for(int i=0;i<length();++i) {
938 System.out.print(obj.getClass().getSimpleName());
939 if(obj instanceof Token) {
940 Token t = (Token)obj;
941 System.out.print("(" + t.text + ")");
943 if(obj instanceof Symbol) {
944 Symbol s = (Symbol)obj;
945 System.out.print("["+ Locations.beginOf(s.location) + "-" + Locations.endOf(s.location) + "]");
947 System.out.print(" ");
949 System.out.println("-> " + reduced.getClass().getSimpleName() + " " +
950 Locations.beginOf(sym.location) + "-" + Locations.endOf(sym.location));*/
954 protected RuntimeException syntaxError(Token token, String description) {
955 throw new SCLSyntaxErrorException(token.location, description);
959 protected Object reduceIdAccessor() {
960 return new IdAccessor(((Token)get(0)).text);
964 protected Object reduceStringAccessor() {
965 return new StringAccessor(((Token)get(1)).text);
969 protected Object reduceExpAccessor() {
970 return new ExpressionAccessor((Expression)get(1));
974 protected Object reduceFieldAccess() {
977 FieldAccessor[] accessors = new FieldAccessor[length()/2];
978 for(int i=0;i<accessors.length;++i) {
979 FieldAccessor accessor = (FieldAccessor)get(i*2+2);
980 accessor.accessSeparator = ((Token)get(i*2+1)).text.charAt(0);
981 accessors[i] = accessor;
983 return new EFieldAccess((Expression)get(0), accessors);
987 protected Object reduceQueryBlock() {
989 return Query.EMPTY_ARRAY;
990 Query[] queries = new Query[length()/2];
991 for(int i=0;i<queries.length;++i)
992 queries[i] = (Query)get(2*i+1);
997 protected Object reduceGuardQuery() {
998 return new QPreGuard((Expression)get(0));
1002 protected Object reduceEqualsQuery() {
1003 return new QPreEquals((Expression)get(0), (Expression)get(2));
1007 protected Object reduceBindQuery() {
1008 return new QPreBinds((Expression)get(0), (Expression)get(2));
1012 protected Object reduceCompositeQuery() {
1013 Query[] queries = (Query[])get(1);
1014 switch(((Token)get(0)).text.charAt(1)) {
1015 case '&': return new QConjunction(queries);
1016 case '|': return new QDisjunction(queries);
1017 case '!': return new QNegation(new QConjunction(queries));
1018 case '?': return new QAlternative(queries);
1019 default: throw new InternalCompilerError();
1024 protected Object reduceRuleStatement() {
1025 return new RuleStatement((Expression)get(0), new QConjunction((Query[])get(2)));
1029 protected Object reduceEntityTypeAnnotation() {
1030 return new EEntityTypeAnnotation((Expression)get(0), (Token)get(2),
1032 ? new QConjunction((Query[])get(length()-1))
1037 protected Object reduceHashedId() {
1038 return new EVar("#" + ((Token)get(1)).text);
1042 protected Object reduceStringLiteral() {
1043 int expCount = length()/3;
1045 return new ELiteral(new StringConstant(((Token)get(1)).text));
1047 String[] strings = new String[expCount+1];
1048 Expression[] expressions = new Expression[expCount];
1049 for(int i=0;i<expCount;++i) {
1050 strings[i] = ((Token)get(i*3+1)).text;
1051 expressions[i] = (Expression)get(i*3+2);
1053 strings[expCount] = ((Token)get(expCount*3+1)).text;
1054 return new EStringLiteral(strings, expressions);
1059 protected Object reduceOneCommand() {
1064 protected Object reduceManyCommands() {
1069 protected Object reduceStatementCommand() {
1070 // to be extended in subclasses
1075 protected Object reduceImportCommand() {
1076 // to be extended in subclasses
1081 protected Object reduceImportValueItem() {
1082 return new EVar(((Token)get(0)).text);
1086 protected Object reduceImportHiding() {
1087 EVar[] values = new EVar[(length()-2)/2];
1088 for(int i=0;i<values.length;++i)
1089 values[i] = (EVar)get(i*2+2);
1090 return new ImportDeclaration.ImportSpec(true, values);
1094 protected Object reduceImportShowing() {
1095 EVar[] values = new EVar[(length()-1)/2];
1096 for(int i=0;i<values.length;++i)
1097 values[i] = (EVar)get(i*2+1);
1098 return new ImportDeclaration.ImportSpec(false, values);
1102 protected Object reduceRuleDeclarations() {
1103 ArrayList<Object> declarations = new ArrayList<Object>(length()/2);
1104 for(int i=1;i<length();i+=2)
1105 declarations.add((Object)get(i));
1106 return declarations;
1109 private static final String[] EMPTY_STRING_ARRAY = new String[0];
1111 @SuppressWarnings("unchecked")
1113 protected Object reduceRuleDefinition() {
1114 String[] extendsNames = EMPTY_STRING_ARRAY;
1116 int extendsCount = (length() - 4) / 2;
1117 extendsNames = new String[extendsCount];
1118 for(int i=0;i<extendsCount;++i)
1119 extendsNames[i] = ((Token)get(3+i*2)).text;
1122 DRuleAst rule = new DRuleAst(
1123 ((Token)get(0)).id == SCLTerminals.ABSTRACT_RULE,
1124 ((Token)get(1)).text,
1127 ArrayList<Object> ruleDeclarations = (ArrayList<Object>)get(length()-1);
1128 ArrayList<Query> section = null;
1129 for(Object decl : ruleDeclarations) {
1130 if(decl instanceof DAnnotationAst) {
1131 DAnnotationAst annotation = (DAnnotationAst)decl;
1132 section = rule.getSection(annotation.id.text.substring(1));
1134 else if(decl instanceof Query) {
1136 section = rule.getSection("when");
1137 section.add((Query)decl);
1140 throw new InternalCompilerError();
1146 protected Object reduceQueryRuleDeclaration() {
1151 protected Object reduceMappingRelationDefinition() {
1152 TypeAst[] types = new TypeAst[length()-2];
1153 for(int i=0;i<types.length;++i)
1154 types[i] = (TypeAst)get(i+2);
1155 return new DMappingRelationAst(
1156 ((Token)get(1)).text,
1161 protected Object reduceTransformation() {
1162 return new ETransformation(
1163 ((Token)get(1)).text,
1164 new QConjunction((Query[])get(3))
1168 @SuppressWarnings("unchecked")
1170 protected Object reduceRelationDefinition() {
1171 return new DRelationAst((Expression)get(0),
1172 ((ArrayList<Object>)get(2)).toArray());
1176 protected Object reduceRecord() {
1177 FieldAssignment[] fields = new FieldAssignment[length()/2-1];
1178 for(int i=0;i<fields.length;++i)
1179 fields[i] = (FieldAssignment)get(2+i*2);
1180 return new ERecord((Token)get(0), fields);
1184 protected Object reduceField() {
1185 return new FieldAssignment(((Token)get(0)).text, (Expression)get(2));
1189 protected Object reduceFieldShorthand() {
1190 return new FieldAssignment(((Token)get(0)).text, null);
1194 protected Object reduceRecordConstructor() {
1196 for(idPos=0;idPos<length();idPos+=2)
1197 if(((Token)get(idPos)).id == SCLTerminals.ID)
1199 DAnnotationAst[] annotations = idPos == 0 ? DAnnotationAst.EMPTY_ARRAY : new DAnnotationAst[idPos/2];
1200 for(int i=0;i<idPos/2;++i)
1201 annotations[i] = new DAnnotationAst((Token)get(i*2),
1202 Arrays.asList((Expression)get(i*2+1)));
1203 TypeAst[] parameters = new TypeAst[(length()-idPos-1)/2];
1204 String[] fieldNames = new String[parameters.length];
1205 for(int i=0;i<parameters.length;++i) {
1206 FieldDescription fieldDesc = (FieldDescription)get(idPos+(i+1)*2);
1207 parameters[i] = fieldDesc.type;
1208 fieldNames[i] = fieldDesc.name;
1210 return new ConstructorAst(annotations, ((Token)get(idPos)).text, parameters, fieldNames);
1214 protected Object reduceFieldDescription() {
1215 return new FieldDescription(((Token)get(0)).text, (TypeAst)get(2));
1219 protected Object reduceEq() {
1220 return (Expression)get(2);
1224 protected Object reduceEquationBlock() {
1226 return new EEquations(Equation.EMPTY_ARRAY);
1227 Equation[] equations = new Equation[length()/2+1];
1228 for(int i=0;i<equations.length;++i)
1229 equations[i] = (Equation)get(2*i);
1230 return new EEquations(equations);
1234 protected Object reduceGuardEquation() {
1235 return new EqGuard((Expression)get(0));
1239 protected Object reduceBasicEquation() {
1240 return new EqBasic((Expression)get(0), (Expression)get(2));
1244 protected Object reduceViewPattern() {
1245 return new EViewPattern((Expression)get(1), (Expression)get(3));
1249 protected Object reduceCHRStatement() {
1250 return new CHRStatement((ListQualifier[])get(0), (ListQualifier[])get(2));
1254 protected Object reduceConstraintStatement() {
1255 TypeAst[] parameterTypes = new TypeAst[length()-2];
1256 for(int i=0;i<parameterTypes.length;++i)
1257 parameterTypes[i] = (TypeAst)get(2+i);
1258 return new ConstraintStatement((Token)get(1), parameterTypes);
1262 protected Object reduceCHRQuery() {
1263 ListQualifier[] query = new ListQualifier[(length()+1)/2];
1264 for(int i=0;i<query.length;++i)
1265 query[i] = (ListQualifier)get(i*2);
1271 protected Object reduceWhen() {
1273 new QConjunction((Query[])get(1)),
1274 (Expression)get(3));
1278 protected Object reduceVerboseCHRQuery() {
1279 ListQualifier[] query = new ListQualifier[(length()-1)/2];
1280 for(int i=0;i<query.length;++i)
1281 query[i] = (ListQualifier)get(i*2+1);
1286 protected Object reduceVerboseCHRStatement() {
1287 return new CHRStatement((ListQualifier[])get(1), (ListQualifier[])get(3));
1291 protected Object reduceDummy() {
1292 throw new UnsupportedOperationException();