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.EPreCHRSelect;
35 import org.simantics.scl.compiler.elaboration.expressions.ERange;
36 import org.simantics.scl.compiler.elaboration.expressions.ERealLiteral;
37 import org.simantics.scl.compiler.elaboration.expressions.ERecord;
38 import org.simantics.scl.compiler.elaboration.expressions.ESelect;
39 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
40 import org.simantics.scl.compiler.elaboration.expressions.EStringLiteral;
41 import org.simantics.scl.compiler.elaboration.expressions.ETransformation;
42 import org.simantics.scl.compiler.elaboration.expressions.ETypeAnnotation;
43 import org.simantics.scl.compiler.elaboration.expressions.EVar;
44 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
45 import org.simantics.scl.compiler.elaboration.expressions.EViewPattern;
46 import org.simantics.scl.compiler.elaboration.expressions.Expression;
47 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpression;
48 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpressionGroup;
49 import org.simantics.scl.compiler.elaboration.expressions.Variable;
50 import org.simantics.scl.compiler.elaboration.expressions.accessor.ExpressionAccessor;
51 import org.simantics.scl.compiler.elaboration.expressions.accessor.FieldAccessor;
52 import org.simantics.scl.compiler.elaboration.expressions.accessor.IdAccessor;
53 import org.simantics.scl.compiler.elaboration.expressions.accessor.StringAccessor;
54 import org.simantics.scl.compiler.elaboration.expressions.block.BindStatement;
55 import org.simantics.scl.compiler.elaboration.expressions.block.CHRStatement;
56 import org.simantics.scl.compiler.elaboration.expressions.block.ConstraintStatement;
57 import org.simantics.scl.compiler.elaboration.expressions.block.GuardStatement;
58 import org.simantics.scl.compiler.elaboration.expressions.block.IncludeStatement;
59 import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement;
60 import org.simantics.scl.compiler.elaboration.expressions.block.RuleStatement;
61 import org.simantics.scl.compiler.elaboration.expressions.block.Statement;
62 import org.simantics.scl.compiler.elaboration.expressions.list.ListAssignment;
63 import org.simantics.scl.compiler.elaboration.expressions.list.ListGenerator;
64 import org.simantics.scl.compiler.elaboration.expressions.list.ListGuard;
65 import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifier;
66 import org.simantics.scl.compiler.elaboration.expressions.list.ListSeq;
67 import org.simantics.scl.compiler.elaboration.expressions.list.ListThen;
68 import org.simantics.scl.compiler.elaboration.expressions.records.FieldAssignment;
69 import org.simantics.scl.compiler.elaboration.java.Builtins;
70 import org.simantics.scl.compiler.elaboration.query.QAlternative;
71 import org.simantics.scl.compiler.elaboration.query.QConjunction;
72 import org.simantics.scl.compiler.elaboration.query.QDisjunction;
73 import org.simantics.scl.compiler.elaboration.query.QNegation;
74 import org.simantics.scl.compiler.elaboration.query.Query;
75 import org.simantics.scl.compiler.elaboration.query.pre.QPreBinds;
76 import org.simantics.scl.compiler.elaboration.query.pre.QPreEquals;
77 import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard;
78 import org.simantics.scl.compiler.errors.Locations;
79 import org.simantics.scl.compiler.internal.header.ModuleHeader;
80 import org.simantics.scl.compiler.internal.parsing.Symbol;
81 import org.simantics.scl.compiler.internal.parsing.Token;
82 import org.simantics.scl.compiler.internal.parsing.declarations.ConstructorAst;
83 import org.simantics.scl.compiler.internal.parsing.declarations.DAnnotationAst;
84 import org.simantics.scl.compiler.internal.parsing.declarations.DClassAst;
85 import org.simantics.scl.compiler.internal.parsing.declarations.DDataAst;
86 import org.simantics.scl.compiler.internal.parsing.declarations.DDerivingInstanceAst;
87 import org.simantics.scl.compiler.internal.parsing.declarations.DDocumentationAst;
88 import org.simantics.scl.compiler.internal.parsing.declarations.DEffectAst;
89 import org.simantics.scl.compiler.internal.parsing.declarations.DFixityAst;
90 import org.simantics.scl.compiler.internal.parsing.declarations.DImportJavaAst;
91 import org.simantics.scl.compiler.internal.parsing.declarations.DInstanceAst;
92 import org.simantics.scl.compiler.internal.parsing.declarations.DMappingRelationAst;
93 import org.simantics.scl.compiler.internal.parsing.declarations.DRelationAst;
94 import org.simantics.scl.compiler.internal.parsing.declarations.DRuleAst;
95 import org.simantics.scl.compiler.internal.parsing.declarations.DRulesetAst;
96 import org.simantics.scl.compiler.internal.parsing.declarations.DTypeAst;
97 import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst;
98 import org.simantics.scl.compiler.internal.parsing.declarations.DValueTypeAst;
99 import org.simantics.scl.compiler.internal.parsing.declarations.DeclarationAst;
100 import org.simantics.scl.compiler.internal.parsing.declarations.FieldDescription;
101 import org.simantics.scl.compiler.internal.parsing.declarations.FundepAst;
102 import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
103 import org.simantics.scl.compiler.internal.parsing.types.TApplyAst;
104 import org.simantics.scl.compiler.internal.parsing.types.TEffectAst;
105 import org.simantics.scl.compiler.internal.parsing.types.TForAllAst;
106 import org.simantics.scl.compiler.internal.parsing.types.TFunctionAst;
107 import org.simantics.scl.compiler.internal.parsing.types.TListAst;
108 import org.simantics.scl.compiler.internal.parsing.types.TPredAst;
109 import org.simantics.scl.compiler.internal.parsing.types.TTupleAst;
110 import org.simantics.scl.compiler.internal.parsing.types.TVarAst;
111 import org.simantics.scl.compiler.internal.parsing.types.TypeAst;
112 import org.simantics.scl.compiler.module.ImportDeclaration;
113 import org.simantics.scl.compiler.types.Types;
116 public class SCLParserImpl extends SCLParser {
118 private final SCLPostLexer lexer;
119 private SCLParserOptions options;
120 private CompilationContext context;
122 public SCLParserImpl(Reader reader) {
123 this.lexer = new SCLPostLexer(reader);
126 public void setCompilationContext(CompilationContext context) {
127 this.context = context;
128 lexer.setCompilationContext(context);
131 public void setParserOptions(SCLParserOptions options) {
132 this.options = options;
133 lexer.setParserOptions(options);
136 public boolean isEmpty() throws Exception {
137 return lexer.peekToken().id == SCLTerminals.EOF;
141 protected Token nextToken() {
143 Token token = lexer.nextToken();
144 /*System.out.println("TOKEN " + token.text + " (" + TERMINAL_NAMES[token.id] + ")" +
146 + Locations.beginOf(token.location) + ".."
147 + Locations.endOf(token.location) + "]");*/
149 } catch(Exception e) {
150 if(e instanceof RuntimeException)
151 throw (RuntimeException)e;
153 throw new RuntimeException(e);
158 protected Object reduceDeclarations() {
159 ArrayList<DeclarationAst> declarations = new ArrayList<DeclarationAst>(length()/2);
160 for(int i=1;i<length();i+=2)
161 declarations.add((DeclarationAst)get(i));
166 protected Object reduceModule() {
167 ArrayList<DeclarationAst> declarations = new ArrayList<DeclarationAst>(length()/2+1);
168 for(int i=0;i<length();i+=2) {
169 DeclarationAst declaration = (DeclarationAst)get(i);
170 if(declaration == null)
172 declarations.add(declaration);
178 protected Object reduceModuleHeader() {
179 FieldAssignment[] fields = new FieldAssignment[length()/2-1];
180 for(int i=0;i<fields.length;++i)
181 fields[i] = (FieldAssignment)get(2+i*2);
182 context.header = ModuleHeader.process(context.errorLog, fields);
187 protected Object reduceLocalTypeAnnotation() {
190 return new ETypeAnnotation((Expression)get(0), (TypeAst)get(2));
194 protected Object reduceTypeAnnotation() {
195 EVar[] names = new EVar[length()/2];
196 for(int i=0;i<names.length;++i)
197 names[i] = (EVar)get(i*2);
198 return new DValueTypeAst(
200 (TypeAst)get(length()-1)
205 protected Object reduceValueDefinition() {
206 Expression rhs = (Expression)get(1);
207 return new DValueAst((Expression)get(0), rhs);
211 protected Object reduceDataDefinition() {
213 ArrayList<String> parameters = new ArrayList<String>();
214 while(i < length()) {
215 Token token = (Token)get(i++);
216 if(token.id != SCLTerminals.ID)
218 parameters.add(token.text);
220 ArrayList<ConstructorAst> constructors = new ArrayList<ConstructorAst>();
221 for(;i < length();i+=2)
222 constructors.add((ConstructorAst)get(i));
224 ((Token)get(1)).text,
225 parameters.toArray(new String[parameters.size()]),
226 constructors.toArray(new ConstructorAst[constructors.size()]),
232 protected Object reduceTypeDefinition() {
234 ArrayList<String> parameters = new ArrayList<String>();
236 Token token = (Token)get(i++);
237 if(token.id != SCLTerminals.ID)
239 parameters.add(token.text);
242 ((Token)get(1)).text,
243 parameters.toArray(new String[parameters.size()]),
248 @SuppressWarnings("unchecked")
250 protected Object reduceClassDefinition() {
252 ArrayList<TypeAst> context;
253 if(get(i) instanceof Token)
254 context = new ArrayList<TypeAst>(0);
256 context = (ArrayList<TypeAst>)get(i++);
257 String name = ((Token)get(i++)).text;
258 ArrayList<String> parameters = new ArrayList<String>();
259 while(i < length()) {
260 Token token = (Token)get(i);
261 if(token.id != SCLTerminals.ID)
263 parameters.add(token.text);
266 ArrayList<DeclarationAst> declarations = null;
267 FundepAst[] fundeps = FundepAst.EMPTY_ARRAY;
268 while(i < length()) {
269 Token token = (Token)get(i++);
270 if(token.id == SCLTerminals.WHERE) {
271 declarations = (ArrayList<DeclarationAst>)get(i++);
273 else if(token.id == SCLTerminals.BAR) {
274 fundeps = (FundepAst[])get(i++);
277 throw new InternalCompilerError();
279 return new DClassAst(context, name,
280 parameters.toArray(new String[parameters.size()]),
286 protected Object reduceFundep() {
287 String[] from = new String[length()-2];
288 for(int i=0;i<from.length;++i)
289 from[i] = ((Token)get(i)).text;
290 String to = ((Token)get(length()-1)).text;
291 return new FundepAst(from, to);
295 protected Object reduceFundeps() {
296 FundepAst[] fundeps = new FundepAst[(length()+1)/2];
297 for(int i=0;i<fundeps.length;++i)
298 fundeps[i] = (FundepAst)get(i*2);
302 @SuppressWarnings("unchecked")
304 protected Object reduceInstanceDefinition() {
306 ArrayList<TypeAst> context;
307 if(get(i) instanceof Token)
308 context = new ArrayList<TypeAst>(0);
310 context = (ArrayList<TypeAst>)get(i++);
311 Token nameToken = (Token)get(i++);
312 EVar name = new EVar(nameToken);
313 ArrayList<TypeAst> parameters = new ArrayList<TypeAst>();
314 while(i < length()) {
315 Object symbol = get(i++);
316 if(symbol instanceof Token)
318 parameters.add((TypeAst)symbol);
320 ArrayList<DeclarationAst> declarations = null;
322 declarations = (ArrayList<DeclarationAst>)get(i);
323 return new DInstanceAst(context, name,
324 parameters.toArray(new TypeAst[parameters.size()]),
328 @SuppressWarnings("unchecked")
330 protected Object reduceDerivingInstanceDefinition() {
332 ArrayList<TypeAst> context;
333 if(get(i) instanceof Token)
334 context = new ArrayList<TypeAst>(0);
336 context = (ArrayList<TypeAst>)get(i++);
337 Token nameToken = (Token)get(i++);
338 EVar name = new EVar(nameToken);
339 ArrayList<TypeAst> parameters = new ArrayList<TypeAst>();
340 while(i < length()) {
341 Object symbol = get(i++);
342 parameters.add((TypeAst)symbol);
344 return new DDerivingInstanceAst(context, name,
345 parameters.toArray(new TypeAst[parameters.size()]));
349 protected Object reduceDocumentationString() {
350 return new DDocumentationAst(((Token)get(1)).text);
354 protected Object reduceAnnotation() {
355 ArrayList<Expression> parameters = new ArrayList<Expression>(length()-1);
356 for(int i=1;i<length();++i)
357 parameters.add((Expression)get(i));
358 return new DAnnotationAst((Token)get(0), parameters);
362 protected Object reducePrecedenceDefinition() {
363 EVar[] symbols = new EVar[length()/2];
364 for(int i=0;i<symbols.length;++i)
365 symbols[i] = (EVar)get(2*i + 2);
366 Associativity associativity;
367 Token token = (Token)get(0);
368 if(token.text.equals("infixl"))
369 associativity = Associativity.LEFT;
370 else if(token.text.equals("infixr"))
371 associativity = Associativity.RIGHT;
373 associativity = Associativity.NONASSOC;
374 return new DFixityAst(
376 Integer.parseInt(((Token)get(1)).text),
382 protected Object reduceImport() {
383 // (AS ID)? importSpec?
385 String importKeyword = ((Token)get(pos++)).text; // (IMPORT | INCLUDE)
386 ++pos; // BEGIN_STRING
387 String moduleName = ((Token)get(pos++)).text; // END_STRING
388 String localName = "";
390 Object temp = get(pos);
391 if(temp instanceof Token) {
392 Token token = (Token)temp;
393 if(token.id == SCLTerminals.AS) {
395 localName = ((Token)get(pos++)).text; // ID
399 ImportDeclaration.ImportSpec spec = ImportDeclaration.DEFAULT_SPEC;
401 spec = (ImportDeclaration.ImportSpec)get(pos++);
402 return new ImportDeclaration(moduleName, localName,
403 importKeyword.equals("include"),
408 protected Object reduceJustImport() {
412 @SuppressWarnings("unchecked")
414 protected Object reduceImportJava() {
415 return new DImportJavaAst(((Token)get(2)).text, (ArrayList<DeclarationAst>)get(4));
419 protected Object reduceEffectDefinition() {
420 return new DEffectAst(
421 ((Token)get(1)).text,
422 ((Token)get(3)).text,
423 ((Token)get(5)).text);
427 protected Object reduceVarId() {
428 return new EVar((Token)get(0));
432 protected Object reduceEscapedSymbol() {
433 return new EVar((Token)get(0));
437 protected Object reduceTupleTypeConstructor() {
438 return new TVarAst(Types.tupleConstructor(length()-1).name);
442 protected Object reduceArrow() {
444 TypeAst result = (TypeAst)get(i);
447 if( ((Token)get(i+1)).text.equals("=>") )
448 result = new TPredAst((TypeAst)get(i), result);
450 result = new TFunctionAst((TypeAst)get(i), result);
457 protected Object reduceBinary() {
461 EVar negation = null;
462 if(get(i) instanceof Token) {
463 Token token = (Token)get(i++);
464 negation = new EVar(token);
466 EBinary binary = new EBinary((Expression)get(i++), negation);
467 while(i < length()) {
468 EVar operator = (EVar)get(i++);
469 Expression right = (Expression)get(i++);
470 binary.rights.add(new EBinaryRightSide(operator, right));
476 protected Object reduceSimpleRhs() {
480 EBlock block = (EBlock)get(3);
481 Expression expression = (Expression)get(1);
482 block.addStatement(new GuardStatement(expression));
483 block.location = Locations.location(Locations.beginOf(expression.location), Locations.endOf(block.location));
488 private GuardedExpressionGroup reduceGuardedExpressionGroup(int length) {
489 GuardedExpression[] expressions = new GuardedExpression[length];
490 for(int i=0;i<expressions.length;++i) {
491 expressions[i] = (GuardedExpression)get(i);
493 return new GuardedExpressionGroup(expressions);
497 protected Object reduceGuardedRhs() {
498 int length = length();
499 if(length > 2 && get(length-2) instanceof Token) {
500 EBlock block = (EBlock)get(length-1);
501 block.addStatement(new GuardStatement(reduceGuardedExpressionGroup(length-2)));
502 block.location = Locations.NO_LOCATION;
506 return reduceGuardedExpressionGroup(length);
510 protected Object reduceStatements() {
511 EBlock block = new EBlock();
513 for(int i=1;i<length();i+=2)
514 block.addStatement((Statement)get(i));
519 protected Object reduceConstructor() {
521 for(idPos=0;idPos<length();idPos+=2)
522 if(((Token)get(idPos)).id == SCLTerminals.ID)
524 DAnnotationAst[] annotations = idPos == 0 ? DAnnotationAst.EMPTY_ARRAY : new DAnnotationAst[idPos/2];
525 for(int i=0;i<idPos/2;++i)
526 annotations[i] = new DAnnotationAst((Token)get(i*2),
527 Arrays.asList((Expression)get(i*2+1)));
528 TypeAst[] parameters = new TypeAst[length()-idPos-1];
529 for(int i=0;i<parameters.length;++i)
530 parameters[i] = (TypeAst)get(i+idPos+1);
531 return new ConstructorAst(annotations, (Token)get(idPos), parameters, null);
535 protected Object reduceContext() {
536 ArrayList<TypeAst> result = new ArrayList<TypeAst>(length()/2-1);
537 for(int i=1;i<length()-2;i+=2)
538 result.add((TypeAst)get(i));
543 protected Object reduceTypeVar() {
544 return new TVarAst(((Token)get(0)).text);
548 protected Object reduceTupleType() {
550 return new TTupleAst(TypeAst.EMPTY_ARRAY);
552 Symbol sym = (Symbol)get(1);
553 sym.location = Locations.NO_LOCATION;
556 int dim = length()/2;
557 TypeAst[] parameters = new TypeAst[dim];
558 for(int i=0;i<dim;++i)
559 parameters[i] = (TypeAst)get(i*2+1);
560 return new TTupleAst(parameters);
564 protected Object reduceListType() {
565 return new TListAst((TypeAst)get(1));
569 protected Object reduceListTypeConstructor() {
570 return new TVarAst("[]");
574 protected Object reduceTupleConstructor() {
575 return new EVar(Types.tupleConstructor(length()-1).name);
579 protected Object reduceVar() {
584 protected Object reduceBlank() {
585 return new EVar(((Token)get(0)).location, "_");
589 protected Object reduceInteger() {
590 return new EIntegerLiteral(((Token)get(0)).text);
594 protected Object reduceFloat() {
595 return new ERealLiteral(((Token)get(0)).text);
599 protected Object reduceString() {
604 protected Object reduceChar() {
605 String text = ((Token)get(0)).text;
606 char c = text.charAt(text.length()-2);
607 if(text.length() == 4) {
609 case 'n': c = '\n'; break;
610 case 't': c = '\t'; break;
611 case 'b': c = '\b'; break;
612 case 'f': c = '\f'; break;
613 case 'r': c = '\r'; break;
616 return new ELiteral(new CharacterConstant(c));
620 protected Object reduceTuple() {
622 return new EConstant(Builtins.TUPLE_CONSTRUCTORS[0]);
624 Symbol sym = (Symbol)get(1);
625 sym.location = Locations.NO_LOCATION;
628 int dim = length()/2;
629 Expression[] parameters = new Expression[dim];
630 for(int i=0;i<dim;++i)
631 parameters[i] = (Expression)get(i*2+1);
632 EConstant tupleConstructor = new EConstant(Builtins.TUPLE_CONSTRUCTORS[dim]);
633 tupleConstructor.location = Locations.location(
634 Locations.beginOf(((Token)get(0)).location),
635 Locations.endOf(((Token)get(length()-1)).location));
636 return new EApply(tupleConstructor, parameters);
639 public static Expression rightSection(EVar op, Expression e) {
640 long loc = Locations.combine(op.location, e.location);
641 Variable var = new Variable("rightSectionTemp");
642 return new ESimpleLambda(loc, var,
643 new EApply(loc, op, new EVariable(loc, var), e));
647 protected Object reduceRightSection() {
648 Variable var = new Variable("rightSectionTemp");
649 long loc = Locations.combine(((Token)get(0)).location, ((Token)get(length()-1)).location);
650 EVar symbol = (EVar)get(1);
651 return new ESimpleLambda(var,
652 new EApply(loc, symbol,
653 new EVariable(loc, var), (Expression)get(2)));
657 protected Object reduceLeftSection() {
658 return new EApply((EVar)get(2), (Expression)get(1));
662 protected Object reduceListLiteral() {
664 return new EListLiteral(Expression.EMPTY_ARRAY);
665 int dim = length()/2;
666 Expression[] components = new Expression[dim];
667 for(int i=0;i<dim;++i)
668 components[i] = (Expression)get(i*2+1);
669 return new EListLiteral(components);
673 protected Object reduceRange() {
681 protected Object reduceListComprehension() {
682 ListQualifier qualifier = (ListQualifier)get(3);
683 for(int i=5;i<length();i+=2) {
684 ListQualifier right = (ListQualifier)get(i);
685 if(right instanceof ListThen) {
686 ((ListThen) right).setLeft(qualifier);
690 qualifier = new ListSeq(qualifier, right);
692 return new EListComprehension((Expression)get(1), qualifier);
696 protected Object reduceAs() {
697 Token id = (Token)get(0);
698 return new EAsPattern(new EVar(id.location, id.text), (Expression)get(2));
702 protected Object reduceGuardedExpEq() {
703 Expression[] guards = new Expression[length()/2-1];
704 for(int i=0;i<guards.length;++i)
705 guards[i] = (Expression)get(i*2+1);
706 return new GuardedExpression(guards, (Expression)get(length()-1));
710 protected Object reduceLambda() {
711 Expression[] patterns = new Expression[length()-3];
712 for(int i=0;i<patterns.length;++i)
713 patterns[i] = (Expression)get(i+1);
714 Case case_ = new Case(patterns, (Expression)get(length()-1));
715 case_.setLhs(Locations.combine(patterns[0].location, patterns[patterns.length-1].location));
716 return new ELambda(case_);
720 protected Object reduceLambdaMatch() {
721 Case[] cases = new Case[length()/2-1];
722 for(int i=0;i<cases.length;++i)
723 cases[i] = (Case)get(i*2+2);
724 return new ELambda(cases);
728 protected Object reduceLet() {
729 EBlock block = (EBlock)get(1);
730 Expression expression = (Expression)get(3);
731 block.addStatement(new GuardStatement(expression));
732 Token letToken = (Token)get(0);
733 block.location = Locations.location(
734 Locations.beginOf(letToken.location),
735 Locations.endOf(expression.location));
740 protected Object reduceIf() {
744 length() == 6 ? (Expression)get(5) : null);
748 protected Object reduceMatch() {
749 Case[] cases = new Case[length()/2-2];
750 for(int i=0;i<cases.length;++i)
751 cases[i] = (Case)get(i*2+4);
752 return new EMatch((Expression)get(1), cases);
756 protected Object reduceDo() {
757 EBlock block = (EBlock)get(1);
758 Token doToken = (Token)get(0);
759 block.setMonadic( doToken.text.equals("mdo") );
760 block.location = Locations.location(Locations.beginOf(doToken.location), Locations.endOf(block.location));
765 protected Object reduceSelect() {
766 return new ESelect(((Token)get(0)).id, (Expression)get(1), new QConjunction((Query[])get(3)));
770 protected Object reduceEnforce() {
771 return new EEnforce(new QConjunction((Query[])get(1)));
775 protected Object reduceApply() {
778 Expression[] parameters = new Expression[length()-1];
779 for(int i=0;i<parameters.length;++i)
780 parameters[i] = (Expression)get(i+1);
781 return new EApply((Expression)get(0), parameters);
785 protected Object reduceSymbol() {
786 return new EVar(((Token)get(0)).text);
790 protected Object reduceEscapedId() {
791 return new EVar(((Token)get(0)).text);
795 protected Object reduceMinus() {
796 return new EVar(((Token)get(0)).text);
800 protected Object reduceLess() {
801 return new EVar(((Token)get(0)).text);
805 protected Object reduceGreater() {
806 return new EVar(((Token)get(0)).text);
810 protected Object reduceDot() {
811 return new EVar(((Token)get(0)).text);
815 protected Object reduceCase() {
816 return new Case((Expression)get(0), (Expression)get(1));
820 protected Object reduceGuardQualifier() {
821 return new ListGuard((Expression)get(0));
825 protected Object reduceLetQualifier() {
826 return new ListAssignment((Expression)get(0), (Expression)get(2));
830 protected Object reduceBindQualifier() {
831 return new ListGenerator((Expression)get(0), (Expression)get(2));
835 protected Object reduceThenQualifier() {
836 return new ListThen((Expression)get(1), length()==4 ? (Expression)get(3) : null);
840 protected Object reduceGuardStatement() {
841 return new GuardStatement((Expression)get(0));
845 protected Object reduceLetStatement() {
846 return new LetStatement((Expression)get(0), (Expression)get(1));
850 protected Object reduceBindStatement() {
851 return new BindStatement((Expression)get(0), (Expression)get(2));
855 protected Object reduceSimpleCaseRhs() {
860 protected Object reduceGuardedCaseRhs() {
861 GuardedExpression[] expressions = new GuardedExpression[length()];
862 for(int i=0;i<expressions.length;++i)
863 expressions[i] = (GuardedExpression)get(i);
864 return new GuardedExpressionGroup(expressions);
868 protected Object reduceGuardedExpArrow() {
869 Expression[] guards = new Expression[length()/2-1];
870 for(int i=0;i<guards.length;++i)
871 guards[i] = (Expression)get(i*2+1);
872 return new GuardedExpression(guards, (Expression)get(length()-1));
876 protected Object reduceEffect() {
877 ArrayList<TypeAst> effects = new ArrayList<TypeAst>(length()/2-1);
878 for(int i=1;i<length()-1;i+=2) {
879 Token token = (Token)get(i);
880 TVarAst ast = new TVarAst(token.text);
881 ast.location = token.location;
884 return new TEffectAst(effects, (TypeAst)get(length()-1));
888 protected Object reduceJustEtype() {
893 protected Object reduceForAll() {
894 String[] vars = new String[length()-3];
895 for(int i=0;i<vars.length;++i)
896 vars[i] = ((Token)get(i+1)).text;
897 return new TForAllAst(vars, (TypeAst)get(length()-1));
901 protected Object reduceApplyType() {
902 TypeAst[] parameters = new TypeAst[length()-1];
903 for(int i=0;i<parameters.length;++i)
904 parameters[i] = (TypeAst)get(i+1);
905 return new TApplyAst((TypeAst)get(0), parameters);
908 @SuppressWarnings("unchecked")
910 protected void postReduce(Object reduced) {
911 if(!(reduced instanceof Symbol))
913 Symbol sym = (Symbol)reduced;
914 if(sym.location != Locations.NO_LOCATION || length() == 0)
916 Object first = get(0);
917 if(!(first instanceof Symbol)) {
918 if(first instanceof List) {
919 List<Object> ll = (List<Object>)first;
923 Object[] ll = (Object[])first;
930 Object last = get(length()-1);
931 if(!(last instanceof Symbol)) {
932 if(last instanceof List) {
933 List<Object> ll = (List<Object>)last;
934 last = ll.get(ll.size()-1);
937 Object[] ll = (Object[])last;
939 last = ll[ll.length-1];
941 last = get(length()-2);
944 sym.location = (((Symbol)first).location & 0xffffffff00000000L)
945 | (((Symbol)last).location & 0xffffffffL);
946 /*for(int i=0;i<length();++i) {
948 System.out.print(obj.getClass().getSimpleName());
949 if(obj instanceof Token) {
950 Token t = (Token)obj;
951 System.out.print("(" + t.text + ")");
953 if(obj instanceof Symbol) {
954 Symbol s = (Symbol)obj;
955 System.out.print("["+ Locations.beginOf(s.location) + "-" + Locations.endOf(s.location) + "]");
957 System.out.print(" ");
959 System.out.println("-> " + reduced.getClass().getSimpleName() + " " +
960 Locations.beginOf(sym.location) + "-" + Locations.endOf(sym.location));*/
964 protected RuntimeException syntaxError(Token token, String description) {
965 throw new SCLSyntaxErrorException(token.location, description);
969 protected Object reduceIdAccessor() {
970 return new IdAccessor('.', ((Token)get(0)).text);
974 protected Object reduceStringAccessor() {
975 return new StringAccessor('.', ((Token)get(1)).text);
979 protected Object reduceExpAccessor() {
980 return new ExpressionAccessor('.', (Expression)get(1));
984 protected Object reduceFieldAccess() {
987 Expression result = (Expression)get(0);
988 for(int i=2;i<length();i+=2) {
989 FieldAccessor accessor = (FieldAccessor)get(i);
990 accessor.accessSeparator = ((Token)get(i-1)).text.charAt(0);
991 result = new EFieldAccess(result, accessor);
997 protected Object reduceQueryBlock() {
999 return Query.EMPTY_ARRAY;
1000 Query[] queries = new Query[length()/2];
1001 for(int i=0;i<queries.length;++i)
1002 queries[i] = (Query)get(2*i+1);
1007 protected Object reduceGuardQuery() {
1008 return new QPreGuard((Expression)get(0));
1012 protected Object reduceEqualsQuery() {
1013 return new QPreEquals((Expression)get(0), (Expression)get(2));
1017 protected Object reduceBindQuery() {
1018 return new QPreBinds((Expression)get(0), (Expression)get(2));
1022 protected Object reduceCompositeQuery() {
1023 Query[] queries = (Query[])get(1);
1024 switch(((Token)get(0)).text.charAt(1)) {
1025 case '&': return new QConjunction(queries);
1026 case '|': return new QDisjunction(queries);
1027 case '!': return new QNegation(new QConjunction(queries));
1028 case '?': return new QAlternative(queries);
1029 default: throw new InternalCompilerError();
1034 protected Object reduceRuleStatement() {
1035 return new RuleStatement((Expression)get(0), new QConjunction((Query[])get(2)));
1039 protected Object reduceHashedId() {
1040 return new EVar("#" + ((Token)get(1)).text);
1044 protected Object reduceStringLiteral() {
1045 int expCount = length()/3;
1047 return new ELiteral(new StringConstant(((Token)get(1)).text));
1049 String[] strings = new String[expCount+1];
1050 Expression[] expressions = new Expression[expCount];
1051 for(int i=0;i<expCount;++i) {
1052 strings[i] = ((Token)get(i*3+1)).text;
1053 expressions[i] = (Expression)get(i*3+2);
1055 strings[expCount] = ((Token)get(expCount*3+1)).text;
1056 return new EStringLiteral(strings, expressions);
1061 protected Object reduceOneCommand() {
1066 protected Object reduceManyCommands() {
1071 protected Object reduceStatementCommand() {
1072 // to be extended in subclasses
1077 protected Object reduceImportCommand() {
1078 // to be extended in subclasses
1083 protected Object reduceImportValueItem() {
1084 return new EVar(((Token)get(0)).text);
1088 protected Object reduceImportHiding() {
1089 EVar[] values = new EVar[(length()-2)/2];
1090 for(int i=0;i<values.length;++i)
1091 values[i] = (EVar)get(i*2+2);
1092 return new ImportDeclaration.ImportSpec(true, values);
1096 protected Object reduceImportShowing() {
1097 EVar[] values = new EVar[(length()-1)/2];
1098 for(int i=0;i<values.length;++i)
1099 values[i] = (EVar)get(i*2+1);
1100 return new ImportDeclaration.ImportSpec(false, values);
1104 protected Object reduceRuleDeclarations() {
1105 ArrayList<Object> declarations = new ArrayList<Object>(length()/2);
1106 for(int i=1;i<length();i+=2)
1107 declarations.add((Object)get(i));
1108 return declarations;
1111 private static final String[] EMPTY_STRING_ARRAY = new String[0];
1113 @SuppressWarnings("unchecked")
1115 protected Object reduceRuleDefinition() {
1116 String[] extendsNames = EMPTY_STRING_ARRAY;
1118 int extendsCount = (length() - 4) / 2;
1119 extendsNames = new String[extendsCount];
1120 for(int i=0;i<extendsCount;++i)
1121 extendsNames[i] = ((Token)get(3+i*2)).text;
1124 DRuleAst rule = new DRuleAst(
1125 ((Token)get(0)).id == SCLTerminals.ABSTRACT_RULE,
1126 ((Token)get(1)).text,
1129 ArrayList<Object> ruleDeclarations = (ArrayList<Object>)get(length()-1);
1130 ArrayList<Query> section = null;
1131 for(Object decl : ruleDeclarations) {
1132 if(decl instanceof DAnnotationAst) {
1133 DAnnotationAst annotation = (DAnnotationAst)decl;
1134 section = rule.getSection(annotation.id.text.substring(1));
1136 else if(decl instanceof Query) {
1138 section = rule.getSection("when");
1139 section.add((Query)decl);
1142 throw new InternalCompilerError();
1148 protected Object reduceQueryRuleDeclaration() {
1153 protected Object reduceMappingRelationDefinition() {
1154 TypeAst[] types = new TypeAst[length()-2];
1155 for(int i=0;i<types.length;++i)
1156 types[i] = (TypeAst)get(i+2);
1157 return new DMappingRelationAst(
1158 ((Token)get(1)).text,
1163 protected Object reduceTransformation() {
1164 return new ETransformation(
1165 ((Token)get(1)).text,
1166 new QConjunction((Query[])get(3))
1170 @SuppressWarnings("unchecked")
1172 protected Object reduceRelationDefinition() {
1173 return new DRelationAst((Expression)get(0),
1174 ((ArrayList<Object>)get(2)).toArray());
1178 protected Object reduceRecord() {
1179 FieldAssignment[] fields = new FieldAssignment[length()/2-1];
1180 for(int i=0;i<fields.length;++i)
1181 fields[i] = (FieldAssignment)get(2+i*2);
1182 return new ERecord(new EVar((Token)get(0)), fields);
1186 protected Object reduceField() {
1187 return new FieldAssignment(((Token)get(0)).text, (Expression)get(2));
1191 protected Object reduceFieldShorthand() {
1192 return new FieldAssignment(((Token)get(0)).text, null);
1196 protected Object reduceRecordConstructor() {
1198 for(idPos=0;idPos<length();idPos+=2)
1199 if(((Token)get(idPos)).id == SCLTerminals.ID)
1201 DAnnotationAst[] annotations = idPos == 0 ? DAnnotationAst.EMPTY_ARRAY : new DAnnotationAst[idPos/2];
1202 for(int i=0;i<idPos/2;++i)
1203 annotations[i] = new DAnnotationAst((Token)get(i*2),
1204 Arrays.asList((Expression)get(i*2+1)));
1205 TypeAst[] parameters = new TypeAst[(length()-idPos-1)/2];
1206 String[] fieldNames = new String[parameters.length];
1207 for(int i=0;i<parameters.length;++i) {
1208 FieldDescription fieldDesc = (FieldDescription)get(idPos+(i+1)*2);
1209 parameters[i] = fieldDesc.type;
1210 fieldNames[i] = fieldDesc.name;
1212 return new ConstructorAst(annotations, (Token)get(idPos), parameters, fieldNames);
1216 protected Object reduceFieldDescription() {
1217 return new FieldDescription(((Token)get(0)).text, (TypeAst)get(2));
1221 protected Object reduceEq() {
1222 return (Expression)get(2);
1226 protected Object reduceEquationBlock() {
1228 return new EEquations(Equation.EMPTY_ARRAY);
1229 Equation[] equations = new Equation[length()/2+1];
1230 for(int i=0;i<equations.length;++i)
1231 equations[i] = (Equation)get(2*i);
1232 return new EEquations(equations);
1236 protected Object reduceGuardEquation() {
1237 return new EqGuard((Expression)get(0));
1241 protected Object reduceBasicEquation() {
1242 return new EqBasic((Expression)get(0), (Expression)get(2));
1246 protected Object reduceViewPattern() {
1247 return new EViewPattern((Expression)get(1), (Expression)get(3));
1251 protected Object reduceCHRStatement() {
1252 return new CHRStatement((ListQualifier[])get(0), (ListQualifier[])get(2));
1256 protected Object reduceConstraintStatement() {
1257 ConstructorAst constructor = (ConstructorAst)get(1);
1258 return new ConstraintStatement(constructor.name, constructor.parameters, constructor.fieldNames, constructor.annotations);
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();
1296 protected Object reduceRulesetDefinition() {
1297 Token name = (Token)get(1);
1298 EBlock block = (EBlock)get(3);
1299 return new DRulesetAst(name.text, block);
1303 protected Object reduceLocalInclude() {
1304 Token name = (Token)get(1);
1305 Expression value = (Expression)get(2);
1306 return new IncludeStatement(name, value);
1310 protected Object reduceConstraintSpec() {
1311 Expression[] expressions = new Expression[length()/2-1];
1312 for(int i=0;i<expressions.length;++i)
1313 expressions[i] = (Expression)get(2*i+1);
1318 protected Object reduceCHRSelect() {
1319 return new EPreCHRSelect((ListQualifier[])get(3), (Expression)get(1));