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.DRelationAst;
91 import org.simantics.scl.compiler.internal.parsing.declarations.DRuleAst;
92 import org.simantics.scl.compiler.internal.parsing.declarations.DTypeAst;
93 import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst;
94 import org.simantics.scl.compiler.internal.parsing.declarations.DValueTypeAst;
95 import org.simantics.scl.compiler.internal.parsing.declarations.DeclarationAst;
96 import org.simantics.scl.compiler.internal.parsing.declarations.FieldDescription;
97 import org.simantics.scl.compiler.internal.parsing.declarations.FundepAst;
98 import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
99 import org.simantics.scl.compiler.internal.parsing.types.TApplyAst;
100 import org.simantics.scl.compiler.internal.parsing.types.TEffectAst;
101 import org.simantics.scl.compiler.internal.parsing.types.TForAllAst;
102 import org.simantics.scl.compiler.internal.parsing.types.TFunctionAst;
103 import org.simantics.scl.compiler.internal.parsing.types.TListAst;
104 import org.simantics.scl.compiler.internal.parsing.types.TPredAst;
105 import org.simantics.scl.compiler.internal.parsing.types.TTupleAst;
106 import org.simantics.scl.compiler.internal.parsing.types.TVarAst;
107 import org.simantics.scl.compiler.internal.parsing.types.TypeAst;
108 import org.simantics.scl.compiler.module.ImportDeclaration;
109 import org.simantics.scl.compiler.types.Types;
112 public class SCLParserImpl extends SCLParser {
114 private final SCLPostLexer lexer;
115 private SCLParserOptions options;
117 public SCLParserImpl(Reader reader) {
118 lexer = new SCLPostLexer(reader);
121 public void setParserOptions(SCLParserOptions options) {
122 this.options = options;
123 lexer.setParserOptions(options);
126 public boolean isEmpty() throws Exception {
127 return lexer.peekToken().id == SCLTerminals.EOF;
131 protected Token nextToken() {
133 Token token = lexer.nextToken();
134 /*System.out.println("TOKEN " + token.text + " (" + TERMINAL_NAMES[token.id] + ")" +
136 + Locations.beginOf(token.location) + ".."
137 + Locations.endOf(token.location) + "]");*/
139 } catch(Exception e) {
140 if(e instanceof RuntimeException)
141 throw (RuntimeException)e;
143 throw new RuntimeException(e);
148 protected Object reduceDeclarations() {
149 ArrayList<DeclarationAst> declarations = new ArrayList<DeclarationAst>(length()/2);
150 for(int i=1;i<length();i+=2)
151 declarations.add((DeclarationAst)get(i));
156 protected Object reduceModule() {
157 ArrayList<DeclarationAst> declarations = new ArrayList<DeclarationAst>(length()/2+1);
158 for(int i=0;i<length();i+=2)
159 declarations.add((DeclarationAst)get(i));
164 protected Object reduceLocalTypeAnnotation() {
167 return new ETypeAnnotation((Expression)get(0), (TypeAst)get(2));
171 protected Object reduceTypeAnnotation() {
172 EVar[] names = new EVar[length()/2];
173 for(int i=0;i<names.length;++i)
174 names[i] = (EVar)get(i*2);
175 return new DValueTypeAst(
177 (TypeAst)get(length()-1)
182 protected Object reduceValueDefinition() {
183 Expression rhs = (Expression)get(1);
184 return new DValueAst((Expression)get(0), rhs);
188 protected Object reduceDataDefinition() {
190 ArrayList<String> parameters = new ArrayList<String>();
191 while(i < length()) {
192 Token token = (Token)get(i++);
193 if(token.id != SCLTerminals.ID)
195 parameters.add(token.text);
197 ArrayList<ConstructorAst> constructors = new ArrayList<ConstructorAst>();
198 for(;i < length();i+=2)
199 constructors.add((ConstructorAst)get(i));
201 ((Token)get(1)).text,
202 parameters.toArray(new String[parameters.size()]),
203 constructors.toArray(new ConstructorAst[constructors.size()]),
209 protected Object reduceTypeDefinition() {
211 ArrayList<String> parameters = new ArrayList<String>();
213 Token token = (Token)get(i++);
214 if(token.id != SCLTerminals.ID)
216 parameters.add(token.text);
219 ((Token)get(1)).text,
220 parameters.toArray(new String[parameters.size()]),
225 @SuppressWarnings("unchecked")
227 protected Object reduceClassDefinition() {
229 ArrayList<TypeAst> context;
230 if(get(i) instanceof Token)
231 context = new ArrayList<TypeAst>(0);
233 context = (ArrayList<TypeAst>)get(i++);
234 String name = ((Token)get(i++)).text;
235 ArrayList<String> parameters = new ArrayList<String>();
236 while(i < length()) {
237 Token token = (Token)get(i);
238 if(token.id != SCLTerminals.ID)
240 parameters.add(token.text);
243 ArrayList<DeclarationAst> declarations = null;
244 FundepAst[] fundeps = FundepAst.EMPTY_ARRAY;
245 while(i < length()) {
246 Token token = (Token)get(i++);
247 if(token.id == SCLTerminals.WHERE) {
248 declarations = (ArrayList<DeclarationAst>)get(i++);
250 else if(token.id == SCLTerminals.BAR) {
251 fundeps = (FundepAst[])get(i++);
254 throw new InternalCompilerError();
256 return new DClassAst(context, name,
257 parameters.toArray(new String[parameters.size()]),
263 protected Object reduceFundep() {
264 String[] from = new String[length()-2];
265 for(int i=0;i<from.length;++i)
266 from[i] = ((Token)get(i)).text;
267 String to = ((Token)get(length()-1)).text;
268 return new FundepAst(from, to);
272 protected Object reduceFundeps() {
273 FundepAst[] fundeps = new FundepAst[(length()+1)/2];
274 for(int i=0;i<fundeps.length;++i)
275 fundeps[i] = (FundepAst)get(i*2);
279 @SuppressWarnings("unchecked")
281 protected Object reduceInstanceDefinition() {
283 ArrayList<TypeAst> context;
284 if(get(i) instanceof Token)
285 context = new ArrayList<TypeAst>(0);
287 context = (ArrayList<TypeAst>)get(i++);
288 Token nameToken = (Token)get(i++);
289 EVar name = new EVar(nameToken.location, nameToken.text);
290 ArrayList<TypeAst> parameters = new ArrayList<TypeAst>();
291 while(i < length()) {
292 Object symbol = get(i++);
293 if(symbol instanceof Token)
295 parameters.add((TypeAst)symbol);
297 ArrayList<DeclarationAst> declarations = null;
299 declarations = (ArrayList<DeclarationAst>)get(i);
300 return new DInstanceAst(context, name,
301 parameters.toArray(new TypeAst[parameters.size()]),
305 @SuppressWarnings("unchecked")
307 protected Object reduceDerivingInstanceDefinition() {
309 ArrayList<TypeAst> context;
310 if(get(i) instanceof Token)
311 context = new ArrayList<TypeAst>(0);
313 context = (ArrayList<TypeAst>)get(i++);
314 Token nameToken = (Token)get(i++);
315 EVar name = new EVar(nameToken.location, nameToken.text);
316 ArrayList<TypeAst> parameters = new ArrayList<TypeAst>();
317 while(i < length()) {
318 Object symbol = get(i++);
319 parameters.add((TypeAst)symbol);
321 return new DDerivingInstanceAst(context, name,
322 parameters.toArray(new TypeAst[parameters.size()]));
326 protected Object reduceDocumentationString() {
327 return new DDocumentationAst(((Token)get(1)).text);
331 protected Object reduceAnnotation() {
332 ArrayList<Expression> parameters = new ArrayList<Expression>(length()-1);
333 for(int i=1;i<length();++i)
334 parameters.add((Expression)get(i));
335 return new DAnnotationAst((Token)get(0), parameters);
339 protected Object reducePrecedenceDefinition() {
340 EVar[] symbols = new EVar[length()/2];
341 for(int i=0;i<symbols.length;++i)
342 symbols[i] = (EVar)get(2*i + 2);
343 Associativity associativity;
344 Token token = (Token)get(0);
345 if(token.text.equals("infixl"))
346 associativity = Associativity.LEFT;
347 else if(token.text.equals("infixr"))
348 associativity = Associativity.RIGHT;
350 associativity = Associativity.NONASSOC;
351 return new DFixityAst(
353 Integer.parseInt(((Token)get(1)).text),
359 protected Object reduceImport() {
360 // (AS ID)? importSpec?
362 String importKeyword = ((Token)get(pos++)).text; // (IMPORT | INCLUDE)
363 ++pos; // BEGIN_STRING
364 String moduleName = ((Token)get(pos++)).text; // END_STRING
365 String localName = "";
367 Object temp = get(pos);
368 if(temp instanceof Token) {
369 Token token = (Token)temp;
370 if(token.id == SCLTerminals.AS) {
372 localName = ((Token)get(pos++)).text; // ID
376 ImportDeclaration.ImportSpec spec = ImportDeclaration.DEFAULT_SPEC;
378 spec = (ImportDeclaration.ImportSpec)get(pos++);
379 return new ImportDeclaration(moduleName, localName,
380 importKeyword.equals("include"),
385 protected Object reduceJustImport() {
389 @SuppressWarnings("unchecked")
391 protected Object reduceImportJava() {
392 return new DImportJavaAst(((Token)get(2)).text, (ArrayList<DeclarationAst>)get(4));
396 protected Object reduceEffectDefinition() {
397 return new DEffectAst(
398 ((Token)get(1)).text,
399 ((Token)get(3)).text,
400 ((Token)get(5)).text);
404 protected Object reduceVarId() {
405 return new EVar(((Token)get(0)).text);
409 protected Object reduceEscapedSymbol() {
410 return new EVar(((Token)get(0)).text);
414 protected Object reduceTupleTypeConstructor() {
415 return new TVarAst(Types.tupleConstructor(length()-1).name);
419 protected Object reduceArrow() {
421 TypeAst result = (TypeAst)get(i);
424 if( ((Token)get(i+1)).text.equals("=>") )
425 result = new TPredAst((TypeAst)get(i), result);
427 result = new TFunctionAst((TypeAst)get(i), result);
434 protected Object reduceBinary() {
438 EVar negation = null;
439 if(get(i) instanceof Token) {
440 Token token = (Token)get(i++);
441 negation = new EVar(token.location, token.text);
443 EBinary binary = new EBinary((Expression)get(i++), negation);
444 while(i < length()) {
445 EVar operator = (EVar)get(i++);
446 Expression right = (Expression)get(i++);
447 binary.rights.add(new EBinaryRightSide(operator, right));
453 protected Object reduceSimpleRhs() {
457 EBlock block = (EBlock)get(3);
458 Expression expression = (Expression)get(1);
459 block.addStatement(new GuardStatement(expression));
460 block.location = Locations.location(Locations.beginOf(expression.location), Locations.endOf(block.location));
465 private GuardedExpressionGroup reduceGuardedExpressionGroup(int length) {
466 GuardedExpression[] expressions = new GuardedExpression[length];
467 for(int i=0;i<expressions.length;++i) {
468 expressions[i] = (GuardedExpression)get(i);
470 return new GuardedExpressionGroup(expressions);
474 protected Object reduceGuardedRhs() {
475 int length = length();
476 if(length > 2 && get(length-2) instanceof Token) {
477 EBlock block = (EBlock)get(length-1);
478 block.addStatement(new GuardStatement(reduceGuardedExpressionGroup(length-2)));
479 block.location = Locations.NO_LOCATION;
483 return reduceGuardedExpressionGroup(length);
487 protected Object reduceStatements() {
488 EBlock block = new EBlock();
490 for(int i=1;i<length();i+=2)
491 block.addStatement((Statement)get(i));
496 protected Object reduceConstructor() {
498 for(idPos=0;idPos<length();idPos+=2)
499 if(((Token)get(idPos)).id == SCLTerminals.ID)
501 DAnnotationAst[] annotations = idPos == 0 ? DAnnotationAst.EMPTY_ARRAY : new DAnnotationAst[idPos/2];
502 for(int i=0;i<idPos/2;++i)
503 annotations[i] = new DAnnotationAst((Token)get(i*2),
504 Arrays.asList((Expression)get(i*2+1)));
505 TypeAst[] parameters = new TypeAst[length()-idPos-1];
506 for(int i=0;i<parameters.length;++i)
507 parameters[i] = (TypeAst)get(i+idPos+1);
508 return new ConstructorAst(annotations, ((Token)get(idPos)).text, parameters, null);
512 protected Object reduceContext() {
513 ArrayList<TypeAst> result = new ArrayList<TypeAst>(length()/2-1);
514 for(int i=1;i<length()-2;i+=2)
515 result.add((TypeAst)get(i));
520 protected Object reduceTypeVar() {
521 return new TVarAst(((Token)get(0)).text);
525 protected Object reduceTupleType() {
527 return new TTupleAst(TypeAst.EMPTY_ARRAY);
529 Symbol sym = (Symbol)get(1);
530 sym.location = Locations.NO_LOCATION;
533 int dim = length()/2;
534 TypeAst[] parameters = new TypeAst[dim];
535 for(int i=0;i<dim;++i)
536 parameters[i] = (TypeAst)get(i*2+1);
537 return new TTupleAst(parameters);
541 protected Object reduceListType() {
542 return new TListAst((TypeAst)get(1));
546 protected Object reduceListTypeConstructor() {
547 return new TVarAst("[]");
551 protected Object reduceTupleConstructor() {
552 return new EVar(Types.tupleConstructor(length()-1).name);
556 protected Object reduceVar() {
561 protected Object reduceBlank() {
562 return new EVar("_");
566 protected Object reduceInteger() {
567 return new EIntegerLiteral(((Token)get(0)).text);
571 protected Object reduceFloat() {
572 return new ERealLiteral(((Token)get(0)).text);
576 protected Object reduceString() {
581 protected Object reduceChar() {
582 String text = ((Token)get(0)).text;
583 char c = text.charAt(text.length()-2);
584 if(text.length() == 4) {
586 case 'n': c = '\n'; break;
587 case 't': c = '\t'; break;
588 case 'b': c = '\b'; break;
589 case 'f': c = '\f'; break;
590 case 'r': c = '\r'; break;
593 return new ELiteral(new CharacterConstant(c));
597 protected Object reduceTuple() {
599 return new EConstant(Builtins.TUPLE_CONSTRUCTORS[0]);
601 Symbol sym = (Symbol)get(1);
602 sym.location = Locations.NO_LOCATION;
605 int dim = length()/2;
606 Expression[] parameters = new Expression[dim];
607 for(int i=0;i<dim;++i)
608 parameters[i] = (Expression)get(i*2+1);
609 EConstant tupleConstructor = new EConstant(Builtins.TUPLE_CONSTRUCTORS[dim]);
610 tupleConstructor.location = Locations.location(
611 Locations.beginOf(((Token)get(0)).location),
612 Locations.endOf(((Token)get(length()-1)).location));
613 return new EApply(tupleConstructor, parameters);
616 public static Expression rightSection(EVar op, Expression e) {
617 long loc = Locations.combine(op.location, e.location);
618 Variable var = new Variable("rightSectionTemp");
619 return new ESimpleLambda(loc, var,
620 new EApply(loc, op, new EVariable(loc, var), e));
624 protected Object reduceRightSection() {
625 Variable var = new Variable("rightSectionTemp");
626 long loc = Locations.combine(((Token)get(0)).location, ((Token)get(length()-1)).location);
627 EVar symbol = (EVar)get(1);
628 return new ESimpleLambda(var,
629 new EApply(loc, symbol,
630 new EVariable(loc, var), (Expression)get(2)));
634 protected Object reduceLeftSection() {
635 return new EApply((EVar)get(2), (Expression)get(1));
639 protected Object reduceListLiteral() {
641 return new EListLiteral(Expression.EMPTY_ARRAY);
642 int dim = length()/2;
643 Expression[] components = new Expression[dim];
644 for(int i=0;i<dim;++i)
645 components[i] = (Expression)get(i*2+1);
646 return new EListLiteral(components);
650 protected Object reduceRange() {
658 protected Object reduceListComprehension() {
659 ListQualifier qualifier = (ListQualifier)get(3);
660 for(int i=5;i<length();i+=2) {
661 ListQualifier right = (ListQualifier)get(i);
662 if(right instanceof ListThen) {
663 ((ListThen) right).setLeft(qualifier);
667 qualifier = new ListSeq(qualifier, right);
669 return new EListComprehension((Expression)get(1), qualifier);
673 protected Object reduceAs() {
674 Token id = (Token)get(0);
675 return new EAsPattern(new EVar(id.location, id.text), (Expression)get(2));
679 protected Object reduceGuardedExpEq() {
680 Expression[] guards = new Expression[length()/2-1];
681 for(int i=0;i<guards.length;++i)
682 guards[i] = (Expression)get(i*2+1);
683 return new GuardedExpression(guards, (Expression)get(length()-1));
687 protected Object reduceLambda() {
688 Expression[] patterns = new Expression[length()-3];
689 for(int i=0;i<patterns.length;++i)
690 patterns[i] = (Expression)get(i+1);
691 Case case_ = new Case(patterns, (Expression)get(length()-1));
692 case_.setLhs(Locations.combine(patterns[0].location, patterns[patterns.length-1].location));
693 return new ELambda(case_);
697 protected Object reduceLambdaMatch() {
698 Case[] cases = new Case[length()/2-1];
699 for(int i=0;i<cases.length;++i)
700 cases[i] = (Case)get(i*2+2);
701 return new ELambda(cases);
705 protected Object reduceLet() {
706 EBlock block = (EBlock)get(1);
707 Expression expression = (Expression)get(3);
708 block.addStatement(new GuardStatement(expression));
709 Token letToken = (Token)get(0);
710 block.location = Locations.location(
711 Locations.beginOf(letToken.location),
712 Locations.endOf(expression.location));
717 protected Object reduceIf() {
721 length() == 6 ? (Expression)get(5) : null);
725 protected Object reduceMatch() {
726 Case[] cases = new Case[length()/2-2];
727 for(int i=0;i<cases.length;++i)
728 cases[i] = (Case)get(i*2+4);
729 return new EMatch((Expression)get(1), cases);
733 protected Object reduceDo() {
734 EBlock block = (EBlock)get(1);
735 Token doToken = (Token)get(0);
736 block.setMonadic( doToken.text.equals("mdo") );
737 block.location = Locations.location(Locations.beginOf(doToken.location), Locations.endOf(block.location));
742 protected Object reduceSelect() {
743 return new ESelect(((Token)get(0)).id, (Expression)get(1), new QConjunction((Query[])get(3)));
747 protected Object reduceEnforce() {
748 return new EEnforce(new QConjunction((Query[])get(1)));
752 protected Object reduceApply() {
755 Expression[] parameters = new Expression[length()-1];
756 for(int i=0;i<parameters.length;++i)
757 parameters[i] = (Expression)get(i+1);
758 return new EApply((Expression)get(0), parameters);
762 protected Object reduceSymbol() {
763 return new EVar(((Token)get(0)).text);
767 protected Object reduceEscapedId() {
768 return new EVar(((Token)get(0)).text);
772 protected Object reduceMinus() {
773 return new EVar(((Token)get(0)).text);
777 protected Object reduceLess() {
778 return new EVar(((Token)get(0)).text);
782 protected Object reduceGreater() {
783 return new EVar(((Token)get(0)).text);
787 protected Object reduceDot() {
788 return new EVar(((Token)get(0)).text);
792 protected Object reduceCase() {
793 return new Case((Expression)get(0), (Expression)get(1));
797 protected Object reduceGuardQualifier() {
798 return new ListGuard((Expression)get(0));
802 protected Object reduceLetQualifier() {
803 return new ListAssignment((Expression)get(0), (Expression)get(2));
807 protected Object reduceBindQualifier() {
808 return new ListGenerator((Expression)get(0), (Expression)get(2));
812 protected Object reduceThenQualifier() {
813 return new ListThen((Expression)get(1), length()==4 ? (Expression)get(3) : null);
817 protected Object reduceGuardStatement() {
818 return new GuardStatement((Expression)get(0));
822 protected Object reduceLetStatement() {
823 return new LetStatement((Expression)get(0), (Expression)get(1));
827 protected Object reduceBindStatement() {
828 return new BindStatement((Expression)get(0), (Expression)get(2));
832 protected Object reduceSimpleCaseRhs() {
837 protected Object reduceGuardedCaseRhs() {
838 GuardedExpression[] expressions = new GuardedExpression[length()];
839 for(int i=0;i<expressions.length;++i)
840 expressions[i] = (GuardedExpression)get(i);
841 return new GuardedExpressionGroup(expressions);
845 protected Object reduceGuardedExpArrow() {
846 Expression[] guards = new Expression[length()/2-1];
847 for(int i=0;i<guards.length;++i)
848 guards[i] = (Expression)get(i*2+1);
849 return new GuardedExpression(guards, (Expression)get(length()-1));
853 protected Object reduceEffect() {
854 ArrayList<TypeAst> effects = new ArrayList<TypeAst>(length()/2-1);
855 for(int i=1;i<length()-1;i+=2) {
856 Token token = (Token)get(i);
857 TVarAst ast = new TVarAst(token.text);
858 ast.location = token.location;
861 return new TEffectAst(effects, (TypeAst)get(length()-1));
865 protected Object reduceJustEtype() {
870 protected Object reduceForAll() {
871 String[] vars = new String[length()-3];
872 for(int i=0;i<vars.length;++i)
873 vars[i] = ((Token)get(i+1)).text;
874 return new TForAllAst(vars, (TypeAst)get(length()-1));
878 protected Object reduceApplyType() {
879 TypeAst[] parameters = new TypeAst[length()-1];
880 for(int i=0;i<parameters.length;++i)
881 parameters[i] = (TypeAst)get(i+1);
882 return new TApplyAst((TypeAst)get(0), parameters);
886 protected Object reduceDummy1() {
887 throw new UnsupportedOperationException();
890 @SuppressWarnings("unchecked")
892 protected void postReduce(Object reduced) {
893 if(!(reduced instanceof Symbol))
895 Symbol sym = (Symbol)reduced;
896 if(sym.location != Locations.NO_LOCATION || length() == 0)
898 Object first = get(0);
899 if(!(first instanceof Symbol)) {
900 if(first instanceof List) {
901 List<Object> ll = (List<Object>)first;
905 Object[] ll = (Object[])first;
912 Object last = get(length()-1);
913 if(!(last instanceof Symbol)) {
914 if(last instanceof List) {
915 List<Object> ll = (List<Object>)last;
916 last = ll.get(ll.size()-1);
919 Object[] ll = (Object[])last;
921 last = ll[ll.length-1];
923 last = get(length()-2);
926 sym.location = (((Symbol)first).location & 0xffffffff00000000L)
927 | (((Symbol)last).location & 0xffffffffL);
928 /*for(int i=0;i<length();++i) {
930 System.out.print(obj.getClass().getSimpleName());
931 if(obj instanceof Token) {
932 Token t = (Token)obj;
933 System.out.print("(" + t.text + ")");
935 if(obj instanceof Symbol) {
936 Symbol s = (Symbol)obj;
937 System.out.print("["+ Locations.beginOf(s.location) + "-" + Locations.endOf(s.location) + "]");
939 System.out.print(" ");
941 System.out.println("-> " + reduced.getClass().getSimpleName() + " " +
942 Locations.beginOf(sym.location) + "-" + Locations.endOf(sym.location));*/
946 protected RuntimeException syntaxError(Token token, String description) {
947 throw new SCLSyntaxErrorException(token.location, description);
951 protected Object reduceIdAccessor() {
952 return new IdAccessor(((Token)get(0)).text);
956 protected Object reduceStringAccessor() {
957 return new StringAccessor(((Token)get(1)).text);
961 protected Object reduceExpAccessor() {
962 return new ExpressionAccessor((Expression)get(1));
966 protected Object reduceFieldAccess() {
969 FieldAccessor[] accessors = new FieldAccessor[length()/2];
970 for(int i=0;i<accessors.length;++i) {
971 FieldAccessor accessor = (FieldAccessor)get(i*2+2);
972 accessor.accessSeparator = ((Token)get(i*2+1)).text.charAt(0);
973 accessors[i] = accessor;
975 return new EFieldAccess((Expression)get(0), accessors);
979 protected Object reduceQueryBlock() {
981 return Query.EMPTY_ARRAY;
982 Query[] queries = new Query[length()/2];
983 for(int i=0;i<queries.length;++i)
984 queries[i] = (Query)get(2*i+1);
989 protected Object reduceGuardQuery() {
990 return new QPreGuard((Expression)get(0));
994 protected Object reduceEqualsQuery() {
995 return new QPreEquals((Expression)get(0), (Expression)get(2));
999 protected Object reduceBindQuery() {
1000 return new QPreBinds((Expression)get(0), (Expression)get(2));
1004 protected Object reduceCompositeQuery() {
1005 Query[] queries = (Query[])get(1);
1006 switch(((Token)get(0)).text.charAt(1)) {
1007 case '&': return new QConjunction(queries);
1008 case '|': return new QDisjunction(queries);
1009 case '!': return new QNegation(new QConjunction(queries));
1010 case '?': return new QAlternative(queries);
1011 default: throw new InternalCompilerError();
1016 protected Object reduceRuleStatement() {
1017 return new RuleStatement((Expression)get(0), new QConjunction((Query[])get(2)));
1021 protected Object reduceEntityTypeAnnotation() {
1022 return new EEntityTypeAnnotation((Expression)get(0), (Token)get(2),
1024 ? new QConjunction((Query[])get(length()-1))
1029 protected Object reduceHashedId() {
1030 return new EVar("#" + ((Token)get(1)).text);
1034 protected Object reduceStringLiteral() {
1035 int expCount = length()/3;
1037 return new ELiteral(new StringConstant(((Token)get(1)).text));
1039 String[] strings = new String[expCount+1];
1040 Expression[] expressions = new Expression[expCount];
1041 for(int i=0;i<expCount;++i) {
1042 strings[i] = ((Token)get(i*3+1)).text;
1043 expressions[i] = (Expression)get(i*3+2);
1045 strings[expCount] = ((Token)get(expCount*3+1)).text;
1046 return new EStringLiteral(strings, expressions);
1051 protected Object reduceOneCommand() {
1056 protected Object reduceManyCommands() {
1061 protected Object reduceStatementCommand() {
1062 // to be extended in subclasses
1067 protected Object reduceImportCommand() {
1068 // to be extended in subclasses
1073 protected Object reduceImportValueItem() {
1074 return new EVar(((Token)get(0)).text);
1078 protected Object reduceImportHiding() {
1079 EVar[] values = new EVar[(length()-2)/2];
1080 for(int i=0;i<values.length;++i)
1081 values[i] = (EVar)get(i*2+2);
1082 return new ImportDeclaration.ImportSpec(true, values);
1086 protected Object reduceImportShowing() {
1087 EVar[] values = new EVar[(length()-1)/2];
1088 for(int i=0;i<values.length;++i)
1089 values[i] = (EVar)get(i*2+1);
1090 return new ImportDeclaration.ImportSpec(false, values);
1094 protected Object reduceRuleDeclarations() {
1095 ArrayList<Object> declarations = new ArrayList<Object>(length()/2);
1096 for(int i=1;i<length();i+=2)
1097 declarations.add((Object)get(i));
1098 return declarations;
1101 private static final String[] EMPTY_STRING_ARRAY = new String[0];
1103 @SuppressWarnings("unchecked")
1105 protected Object reduceRuleDefinition() {
1106 String[] extendsNames = EMPTY_STRING_ARRAY;
1108 int extendsCount = (length() - 4) / 2;
1109 extendsNames = new String[extendsCount];
1110 for(int i=0;i<extendsCount;++i)
1111 extendsNames[i] = ((Token)get(3+i*2)).text;
1114 DRuleAst rule = new DRuleAst(
1115 ((Token)get(0)).id == SCLTerminals.ABSTRACT_RULE,
1116 ((Token)get(1)).text,
1119 ArrayList<Object> ruleDeclarations = (ArrayList<Object>)get(length()-1);
1120 ArrayList<Query> section = null;
1121 for(Object decl : ruleDeclarations) {
1122 if(decl instanceof DAnnotationAst) {
1123 DAnnotationAst annotation = (DAnnotationAst)decl;
1124 section = rule.getSection(annotation.id.text.substring(1));
1126 else if(decl instanceof Query) {
1128 section = rule.getSection("when");
1129 section.add((Query)decl);
1132 throw new InternalCompilerError();
1138 protected Object reduceQueryRuleDeclaration() {
1143 protected Object reduceMappingRelationDefinition() {
1144 TypeAst[] types = new TypeAst[length()-2];
1145 for(int i=0;i<types.length;++i)
1146 types[i] = (TypeAst)get(i+2);
1147 return new DMappingRelationAst(
1148 ((Token)get(1)).text,
1153 protected Object reduceTransformation() {
1154 return new ETransformation(
1155 ((Token)get(1)).text,
1156 new QConjunction((Query[])get(3))
1160 @SuppressWarnings("unchecked")
1162 protected Object reduceRelationDefinition() {
1163 return new DRelationAst((Expression)get(0),
1164 ((ArrayList<Object>)get(2)).toArray());
1168 protected Object reduceRecord() {
1169 FieldAssignment[] fields = new FieldAssignment[length()/2-1];
1170 for(int i=0;i<fields.length;++i)
1171 fields[i] = (FieldAssignment)get(2+i*2);
1172 return new ERecord((Token)get(0), fields);
1176 protected Object reduceField() {
1177 return new FieldAssignment(((Token)get(0)).text, (Expression)get(2));
1181 protected Object reduceFieldShorthand() {
1182 return new FieldAssignment(((Token)get(0)).text, null);
1186 protected Object reduceRecordConstructor() {
1188 for(idPos=0;idPos<length();idPos+=2)
1189 if(((Token)get(idPos)).id == SCLTerminals.ID)
1191 DAnnotationAst[] annotations = idPos == 0 ? DAnnotationAst.EMPTY_ARRAY : new DAnnotationAst[idPos/2];
1192 for(int i=0;i<idPos/2;++i)
1193 annotations[i] = new DAnnotationAst((Token)get(i*2),
1194 Arrays.asList((Expression)get(i*2+1)));
1195 TypeAst[] parameters = new TypeAst[(length()-idPos-1)/2];
1196 String[] fieldNames = new String[parameters.length];
1197 for(int i=0;i<parameters.length;++i) {
1198 FieldDescription fieldDesc = (FieldDescription)get(idPos+(i+1)*2);
1199 parameters[i] = fieldDesc.type;
1200 fieldNames[i] = fieldDesc.name;
1202 return new ConstructorAst(annotations, ((Token)get(idPos)).text, parameters, fieldNames);
1206 protected Object reduceFieldDescription() {
1207 return new FieldDescription(((Token)get(0)).text, (TypeAst)get(2));
1211 protected Object reduceEq() {
1212 return (Expression)get(2);
1216 protected Object reduceEquationBlock() {
1218 return new EEquations(Equation.EMPTY_ARRAY);
1219 Equation[] equations = new Equation[length()/2+1];
1220 for(int i=0;i<equations.length;++i)
1221 equations[i] = (Equation)get(2*i);
1222 return new EEquations(equations);
1226 protected Object reduceGuardEquation() {
1227 return new EqGuard((Expression)get(0));
1231 protected Object reduceBasicEquation() {
1232 return new EqBasic((Expression)get(0), (Expression)get(2));
1236 protected Object reduceViewPattern() {
1237 return new EViewPattern((Expression)get(1), (Expression)get(3));
1241 protected Object reduceCHRStatement() {
1242 return new CHRStatement((ListQualifier[])get(0), (ListQualifier[])get(2));
1246 protected Object reduceConstraintStatement() {
1247 TypeAst[] parameterTypes = new TypeAst[length()-2];
1248 for(int i=0;i<parameterTypes.length;++i)
1249 parameterTypes[i] = (TypeAst)get(2+i);
1250 return new ConstraintStatement((Token)get(1), parameterTypes);
1254 protected Object reduceCHRQuery() {
1255 ListQualifier[] query = new ListQualifier[(length()+1)/2];
1256 for(int i=0;i<query.length;++i)
1257 query[i] = (ListQualifier)get(i*2);
1263 protected Object reduceWhen() {
1265 new QConjunction((Query[])get(1)),
1266 (Expression)get(3));
1270 protected Object reduceVerboseCHRQuery() {
1271 ListQualifier[] query = new ListQualifier[(length()-1)/2];
1272 for(int i=0;i<query.length;++i)
1273 query[i] = (ListQualifier)get(i*2+1);
1278 protected Object reduceVerboseCHRStatement() {
1279 return new CHRStatement((ListQualifier[])get(1), (ListQualifier[])get(3));