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.chr.ast.CHRAstAtom;
15 import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstBinds;
16 import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstConjunction;
17 import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstEquals;
18 import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstQuery;
19 import org.simantics.scl.compiler.elaboration.equation.EqBasic;
20 import org.simantics.scl.compiler.elaboration.equation.EqGuard;
21 import org.simantics.scl.compiler.elaboration.equation.Equation;
22 import org.simantics.scl.compiler.elaboration.expressions.Case;
23 import org.simantics.scl.compiler.elaboration.expressions.EApply;
24 import org.simantics.scl.compiler.elaboration.expressions.EAsPattern;
25 import org.simantics.scl.compiler.elaboration.expressions.EBinary;
26 import org.simantics.scl.compiler.elaboration.expressions.EBinaryRightSide;
27 import org.simantics.scl.compiler.elaboration.expressions.EBlock;
28 import org.simantics.scl.compiler.elaboration.expressions.EConstant;
29 import org.simantics.scl.compiler.elaboration.expressions.EEnforce;
30 import org.simantics.scl.compiler.elaboration.expressions.EEquations;
31 import org.simantics.scl.compiler.elaboration.expressions.EFieldAccess;
32 import org.simantics.scl.compiler.elaboration.expressions.EIf;
33 import org.simantics.scl.compiler.elaboration.expressions.EIntegerLiteral;
34 import org.simantics.scl.compiler.elaboration.expressions.ELambda;
35 import org.simantics.scl.compiler.elaboration.expressions.EListComprehension;
36 import org.simantics.scl.compiler.elaboration.expressions.EListLiteral;
37 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
38 import org.simantics.scl.compiler.elaboration.expressions.EMatch;
39 import org.simantics.scl.compiler.elaboration.expressions.EPreCHRSelect;
40 import org.simantics.scl.compiler.elaboration.expressions.ERange;
41 import org.simantics.scl.compiler.elaboration.expressions.ERealLiteral;
42 import org.simantics.scl.compiler.elaboration.expressions.ERecord;
43 import org.simantics.scl.compiler.elaboration.expressions.ESelect;
44 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
45 import org.simantics.scl.compiler.elaboration.expressions.EStringLiteral;
46 import org.simantics.scl.compiler.elaboration.expressions.ETransformation;
47 import org.simantics.scl.compiler.elaboration.expressions.ETypeAnnotation;
48 import org.simantics.scl.compiler.elaboration.expressions.EVar;
49 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
50 import org.simantics.scl.compiler.elaboration.expressions.EViewPattern;
51 import org.simantics.scl.compiler.elaboration.expressions.Expression;
52 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpression;
53 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpressionGroup;
54 import org.simantics.scl.compiler.elaboration.expressions.Variable;
55 import org.simantics.scl.compiler.elaboration.expressions.accessor.ExpressionAccessor;
56 import org.simantics.scl.compiler.elaboration.expressions.accessor.FieldAccessor;
57 import org.simantics.scl.compiler.elaboration.expressions.accessor.IdAccessor;
58 import org.simantics.scl.compiler.elaboration.expressions.accessor.StringAccessor;
59 import org.simantics.scl.compiler.elaboration.expressions.block.BindStatement;
60 import org.simantics.scl.compiler.elaboration.expressions.block.BlockType;
61 import org.simantics.scl.compiler.elaboration.expressions.block.CHRStatement;
62 import org.simantics.scl.compiler.elaboration.expressions.block.ConstraintStatement;
63 import org.simantics.scl.compiler.elaboration.expressions.block.GuardStatement;
64 import org.simantics.scl.compiler.elaboration.expressions.block.IncludeStatement;
65 import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement;
66 import org.simantics.scl.compiler.elaboration.expressions.block.RuleStatement;
67 import org.simantics.scl.compiler.elaboration.expressions.block.Statement;
68 import org.simantics.scl.compiler.elaboration.expressions.list.ListAssignment;
69 import org.simantics.scl.compiler.elaboration.expressions.list.ListGenerator;
70 import org.simantics.scl.compiler.elaboration.expressions.list.ListGuard;
71 import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifier;
72 import org.simantics.scl.compiler.elaboration.expressions.list.ListSeq;
73 import org.simantics.scl.compiler.elaboration.expressions.list.ListThen;
74 import org.simantics.scl.compiler.elaboration.expressions.records.FieldAssignment;
75 import org.simantics.scl.compiler.elaboration.java.Builtins;
76 import org.simantics.scl.compiler.elaboration.query.QAlternative;
77 import org.simantics.scl.compiler.elaboration.query.QConjunction;
78 import org.simantics.scl.compiler.elaboration.query.QDisjunction;
79 import org.simantics.scl.compiler.elaboration.query.QNegation;
80 import org.simantics.scl.compiler.elaboration.query.Query;
81 import org.simantics.scl.compiler.elaboration.query.pre.QPreBinds;
82 import org.simantics.scl.compiler.elaboration.query.pre.QPreEquals;
83 import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard;
84 import org.simantics.scl.compiler.errors.Locations;
85 import org.simantics.scl.compiler.internal.header.ModuleHeader;
86 import org.simantics.scl.compiler.internal.parsing.Symbol;
87 import org.simantics.scl.compiler.internal.parsing.Token;
88 import org.simantics.scl.compiler.internal.parsing.declarations.ConstructorAst;
89 import org.simantics.scl.compiler.internal.parsing.declarations.DAnnotationAst;
90 import org.simantics.scl.compiler.internal.parsing.declarations.DClassAst;
91 import org.simantics.scl.compiler.internal.parsing.declarations.DDataAst;
92 import org.simantics.scl.compiler.internal.parsing.declarations.DDerivingInstanceAst;
93 import org.simantics.scl.compiler.internal.parsing.declarations.DDocumentationAst;
94 import org.simantics.scl.compiler.internal.parsing.declarations.DEffectAst;
95 import org.simantics.scl.compiler.internal.parsing.declarations.DFixityAst;
96 import org.simantics.scl.compiler.internal.parsing.declarations.DImportJavaAst;
97 import org.simantics.scl.compiler.internal.parsing.declarations.DInstanceAst;
98 import org.simantics.scl.compiler.internal.parsing.declarations.DMappingRelationAst;
99 import org.simantics.scl.compiler.internal.parsing.declarations.DRelationAst;
100 import org.simantics.scl.compiler.internal.parsing.declarations.DRuleAst;
101 import org.simantics.scl.compiler.internal.parsing.declarations.DRulesetAst;
102 import org.simantics.scl.compiler.internal.parsing.declarations.DTypeAst;
103 import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst;
104 import org.simantics.scl.compiler.internal.parsing.declarations.DValueTypeAst;
105 import org.simantics.scl.compiler.internal.parsing.declarations.DeclarationAst;
106 import org.simantics.scl.compiler.internal.parsing.declarations.FieldDescription;
107 import org.simantics.scl.compiler.internal.parsing.declarations.FundepAst;
108 import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
109 import org.simantics.scl.compiler.internal.parsing.types.TApplyAst;
110 import org.simantics.scl.compiler.internal.parsing.types.TEffectAst;
111 import org.simantics.scl.compiler.internal.parsing.types.TForAllAst;
112 import org.simantics.scl.compiler.internal.parsing.types.TFunctionAst;
113 import org.simantics.scl.compiler.internal.parsing.types.TListAst;
114 import org.simantics.scl.compiler.internal.parsing.types.TPlainEffectAst;
115 import org.simantics.scl.compiler.internal.parsing.types.TPredAst;
116 import org.simantics.scl.compiler.internal.parsing.types.TTupleAst;
117 import org.simantics.scl.compiler.internal.parsing.types.TVarAst;
118 import org.simantics.scl.compiler.internal.parsing.types.TypeAst;
119 import org.simantics.scl.compiler.module.ImportDeclaration;
120 import org.simantics.scl.compiler.types.Types;
123 public class SCLParserImpl extends SCLParser {
125 private final SCLPostLexer lexer;
126 private SCLParserOptions options;
127 private CompilationContext context;
129 public SCLParserImpl(Reader reader) {
130 this.lexer = new SCLPostLexer(reader);
133 public SCLPostLexer getLexer() {
137 public void setCompilationContext(CompilationContext context) {
138 this.context = context;
139 lexer.setCompilationContext(context);
142 public void setParserOptions(SCLParserOptions options) {
143 this.options = options;
144 lexer.setParserOptions(options);
147 public boolean isEmpty() throws Exception {
148 return lexer.peekToken().id == SCLTerminals.EOF;
152 protected Token nextToken() {
154 Token token = lexer.nextToken();
155 /*System.out.println("TOKEN " + token.text + " (" + TERMINAL_NAMES[token.id] + ")" +
157 + Locations.beginOf(token.location) + ".."
158 + Locations.endOf(token.location) + "]");*/
160 } catch(Exception e) {
161 if(e instanceof RuntimeException)
162 throw (RuntimeException)e;
164 throw new RuntimeException(e);
169 protected Object reduceDeclarations() {
170 ArrayList<DeclarationAst> declarations = new ArrayList<DeclarationAst>(length()/2);
171 for(int i=1;i<length();i+=2)
172 declarations.add((DeclarationAst)get(i));
177 protected Object reduceModule() {
178 ArrayList<DeclarationAst> declarations = new ArrayList<DeclarationAst>(length()/2+1);
179 for(int i=0;i<length();i+=2) {
180 DeclarationAst declaration = (DeclarationAst)get(i);
181 if(declaration == null)
183 declarations.add(declaration);
189 protected Object reduceModuleHeader() {
190 FieldAssignment[] fields = new FieldAssignment[length()/2-1];
191 for(int i=0;i<fields.length;++i)
192 fields[i] = (FieldAssignment)get(2+i*2);
193 context.header = ModuleHeader.process(context.errorLog, fields);
198 protected Object reduceLocalTypeAnnotation() {
201 return new ETypeAnnotation((Expression)get(0), (TypeAst)get(2));
205 protected Object reduceTypeAnnotation() {
206 EVar[] names = new EVar[length()/2];
207 for(int i=0;i<names.length;++i)
208 names[i] = (EVar)get(i*2);
209 return new DValueTypeAst(
211 (TypeAst)get(length()-1)
216 protected Object reduceValueDefinition() {
217 Expression rhs = (Expression)get(1);
218 return new DValueAst((Expression)get(0), rhs);
222 protected Object reduceDataDefinition() {
224 ArrayList<String> parameters = new ArrayList<String>();
225 while(i < length()) {
226 Token token = (Token)get(i++);
227 if(token.id != SCLTerminals.ID)
229 parameters.add(token.text);
231 ArrayList<ConstructorAst> constructors = new ArrayList<ConstructorAst>();
232 for(;i < length();i+=2)
233 constructors.add((ConstructorAst)get(i));
235 ((Token)get(1)).text,
236 parameters.toArray(new String[parameters.size()]),
237 constructors.toArray(new ConstructorAst[constructors.size()]),
243 protected Object reduceTypeDefinition() {
245 ArrayList<String> parameters = new ArrayList<String>();
247 Token token = (Token)get(i++);
248 if(token.id != SCLTerminals.ID)
250 parameters.add(token.text);
253 ((Token)get(1)).text,
254 parameters.toArray(new String[parameters.size()]),
259 @SuppressWarnings("unchecked")
261 protected Object reduceClassDefinition() {
263 ArrayList<TypeAst> context;
264 if(get(i) instanceof Token)
265 context = new ArrayList<TypeAst>(0);
267 context = (ArrayList<TypeAst>)get(i++);
268 String name = ((Token)get(i++)).text;
269 ArrayList<String> parameters = new ArrayList<String>();
270 while(i < length()) {
271 Token token = (Token)get(i);
272 if(token.id != SCLTerminals.ID)
274 parameters.add(token.text);
277 ArrayList<DeclarationAst> declarations = null;
278 FundepAst[] fundeps = FundepAst.EMPTY_ARRAY;
279 while(i < length()) {
280 Token token = (Token)get(i++);
281 if(token.id == SCLTerminals.WHERE) {
282 declarations = (ArrayList<DeclarationAst>)get(i++);
284 else if(token.id == SCLTerminals.BAR) {
285 fundeps = (FundepAst[])get(i++);
288 throw new InternalCompilerError();
290 return new DClassAst(context, name,
291 parameters.toArray(new String[parameters.size()]),
297 protected Object reduceFundep() {
298 String[] from = new String[length()-2];
299 for(int i=0;i<from.length;++i)
300 from[i] = ((Token)get(i)).text;
301 String to = ((Token)get(length()-1)).text;
302 return new FundepAst(from, to);
306 protected Object reduceFundeps() {
307 FundepAst[] fundeps = new FundepAst[(length()+1)/2];
308 for(int i=0;i<fundeps.length;++i)
309 fundeps[i] = (FundepAst)get(i*2);
313 @SuppressWarnings("unchecked")
315 protected Object reduceInstanceDefinition() {
317 ArrayList<TypeAst> context;
318 if(get(i) instanceof Token)
319 context = new ArrayList<TypeAst>(0);
321 context = (ArrayList<TypeAst>)get(i++);
322 Token nameToken = (Token)get(i++);
323 EVar name = new EVar(nameToken);
324 ArrayList<TypeAst> parameters = new ArrayList<TypeAst>();
325 while(i < length()) {
326 Object symbol = get(i++);
327 if(symbol instanceof Token)
329 parameters.add((TypeAst)symbol);
331 ArrayList<DeclarationAst> declarations = null;
333 declarations = (ArrayList<DeclarationAst>)get(i);
334 return new DInstanceAst(context, name,
335 parameters.toArray(new TypeAst[parameters.size()]),
339 @SuppressWarnings("unchecked")
341 protected Object reduceDerivingInstanceDefinition() {
343 ArrayList<TypeAst> context;
344 if(get(i) instanceof Token)
345 context = new ArrayList<TypeAst>(0);
347 context = (ArrayList<TypeAst>)get(i++);
348 Token nameToken = (Token)get(i++);
349 EVar name = new EVar(nameToken);
350 ArrayList<TypeAst> parameters = new ArrayList<TypeAst>();
351 while(i < length()) {
352 Object symbol = get(i++);
353 parameters.add((TypeAst)symbol);
355 return new DDerivingInstanceAst(context, name,
356 parameters.toArray(new TypeAst[parameters.size()]));
360 protected Object reduceDocumentationString() {
361 return new DDocumentationAst(((Token)get(1)).text);
365 protected Object reduceAnnotation() {
366 ArrayList<Expression> parameters = new ArrayList<Expression>(length()-1);
367 for(int i=1;i<length();++i)
368 parameters.add((Expression)get(i));
369 return new DAnnotationAst((Token)get(0), parameters);
373 protected Object reducePrecedenceDefinition() {
374 EVar[] symbols = new EVar[length()/2];
375 for(int i=0;i<symbols.length;++i)
376 symbols[i] = (EVar)get(2*i + 2);
377 Associativity associativity;
378 Token token = (Token)get(0);
379 if(token.text.equals("infixl"))
380 associativity = Associativity.LEFT;
381 else if(token.text.equals("infixr"))
382 associativity = Associativity.RIGHT;
384 associativity = Associativity.NONASSOC;
385 return new DFixityAst(
387 Integer.parseInt(((Token)get(1)).text),
393 protected Object reduceImport() {
394 // (AS ID)? importSpec?
396 String importKeyword = ((Token)get(pos++)).text; // (IMPORT | INCLUDE)
397 ++pos; // BEGIN_STRING
398 String moduleName = ((Token)get(pos++)).text; // END_STRING
399 String localName = "";
401 Object temp = get(pos);
402 if(temp instanceof Token) {
403 Token token = (Token)temp;
404 if(token.id == SCLTerminals.AS) {
406 localName = ((Token)get(pos++)).text; // ID
410 ImportDeclaration.ImportSpec spec = ImportDeclaration.DEFAULT_SPEC;
412 spec = (ImportDeclaration.ImportSpec)get(pos++);
413 return new ImportDeclaration(moduleName, localName,
414 importKeyword.equals("include"),
419 protected Object reduceJustImport() {
423 @SuppressWarnings("unchecked")
425 protected Object reduceImportJava() {
426 return new DImportJavaAst(((Token)get(2)).text, (ArrayList<DeclarationAst>)get(4));
430 protected Object reduceEffectDefinition() {
431 return new DEffectAst(
432 ((Token)get(1)).text,
433 ((Token)get(3)).text,
434 ((Token)get(5)).text);
438 protected Object reduceVarId() {
439 return new EVar((Token)get(0));
443 protected Object reduceEscapedSymbol() {
444 return new EVar((Token)get(0));
448 protected Object reduceTupleTypeConstructor() {
449 return new TVarAst(Types.tupleConstructor(length()-1).name);
453 protected Object reduceArrow() {
455 TypeAst result = (TypeAst)get(i);
458 if( ((Token)get(i+1)).text.equals("=>") )
459 result = new TPredAst((TypeAst)get(i), result);
461 result = new TFunctionAst((TypeAst)get(i), result);
468 protected Object reduceBinary() {
472 EVar negation = null;
473 if(get(i) instanceof Token) {
474 Token token = (Token)get(i++);
475 negation = new EVar(token);
477 EBinary binary = new EBinary((Expression)get(i++), negation);
478 while(i < length()) {
479 EVar operator = (EVar)get(i++);
480 Expression right = (Expression)get(i++);
481 binary.rights.add(new EBinaryRightSide(operator, right));
487 protected Object reduceSimpleRhs() {
491 EBlock block = (EBlock)get(3);
492 Expression expression = (Expression)get(1);
493 block.addStatement(new GuardStatement(expression));
494 block.location = Locations.location(Locations.beginOf(expression.location), Locations.endOf(block.location));
499 private GuardedExpressionGroup reduceGuardedExpressionGroup(int length) {
500 GuardedExpression[] expressions = new GuardedExpression[length];
501 for(int i=0;i<expressions.length;++i) {
502 expressions[i] = (GuardedExpression)get(i);
504 return new GuardedExpressionGroup(expressions);
508 protected Object reduceGuardedRhs() {
509 int length = length();
510 if(length > 2 && get(length-2) instanceof Token) {
511 EBlock block = (EBlock)get(length-1);
512 block.addStatement(new GuardStatement(reduceGuardedExpressionGroup(length-2)));
513 block.location = Locations.NO_LOCATION;
517 return reduceGuardedExpressionGroup(length);
521 protected Object reduceStatements() {
522 EBlock block = new EBlock();
524 for(int i=1;i<length();i+=2)
525 block.addStatement((Statement)get(i));
530 protected Object reduceConstructor() {
532 for(idPos=0;idPos<length();idPos+=2)
533 if(((Token)get(idPos)).id == SCLTerminals.ID)
535 DAnnotationAst[] annotations = idPos == 0 ? DAnnotationAst.EMPTY_ARRAY : new DAnnotationAst[idPos/2];
536 for(int i=0;i<idPos/2;++i)
537 annotations[i] = new DAnnotationAst((Token)get(i*2),
538 Arrays.asList((Expression)get(i*2+1)));
539 TypeAst[] parameters = new TypeAst[length()-idPos-1];
540 for(int i=0;i<parameters.length;++i)
541 parameters[i] = (TypeAst)get(i+idPos+1);
542 return new ConstructorAst(annotations, (Token)get(idPos), parameters, null);
546 protected Object reduceContext() {
547 ArrayList<TypeAst> result = new ArrayList<TypeAst>(length()/2-1);
548 for(int i=1;i<length()-2;i+=2)
549 result.add((TypeAst)get(i));
554 protected Object reduceTypeVar() {
555 return new TVarAst(((Token)get(0)).text);
559 protected Object reduceTupleType() {
561 return new TTupleAst(TypeAst.EMPTY_ARRAY);
563 Symbol sym = (Symbol)get(1);
564 sym.location = Locations.NO_LOCATION;
567 int dim = length()/2;
568 TypeAst[] parameters = new TypeAst[dim];
569 for(int i=0;i<dim;++i)
570 parameters[i] = (TypeAst)get(i*2+1);
571 return new TTupleAst(parameters);
575 protected Object reduceListType() {
576 return new TListAst((TypeAst)get(1));
580 protected Object reduceListTypeConstructor() {
581 return new TVarAst("[]");
585 protected Object reduceTupleConstructor() {
586 return new EVar(Types.tupleConstructor(length()-1).name);
590 protected Object reduceVar() {
595 protected Object reduceBlank() {
596 return new EVar(((Token)get(0)).location, "_");
600 protected Object reduceInteger() {
601 return new EIntegerLiteral(((Token)get(0)).text);
605 protected Object reduceFloat() {
606 return new ERealLiteral(((Token)get(0)).text);
610 protected Object reduceString() {
615 protected Object reduceChar() {
616 String text = ((Token)get(0)).text;
617 char c = text.charAt(text.length()-2);
618 if(text.length() == 4) {
620 case 'n': c = '\n'; break;
621 case 't': c = '\t'; break;
622 case 'b': c = '\b'; break;
623 case 'f': c = '\f'; break;
624 case 'r': c = '\r'; break;
627 return new ELiteral(new CharacterConstant(c));
631 protected Object reduceTuple() {
633 return new EConstant(Builtins.TUPLE_CONSTRUCTORS[0]);
635 Symbol sym = (Symbol)get(1);
636 sym.location = Locations.NO_LOCATION;
639 int dim = length()/2;
640 Expression[] parameters = new Expression[dim];
641 for(int i=0;i<dim;++i)
642 parameters[i] = (Expression)get(i*2+1);
643 EConstant tupleConstructor = new EConstant(Builtins.TUPLE_CONSTRUCTORS[dim]);
644 tupleConstructor.location = Locations.location(
645 Locations.beginOf(((Token)get(0)).location),
646 Locations.endOf(((Token)get(length()-1)).location));
647 return new EApply(tupleConstructor, parameters);
650 public static Expression rightSection(EVar op, Expression e) {
651 long loc = Locations.combine(op.location, e.location);
652 Variable var = new Variable("rightSectionTemp");
653 return new ESimpleLambda(loc, var,
654 new EApply(loc, op, new EVariable(loc, var), e));
658 protected Object reduceRightSection() {
659 Variable var = new Variable("rightSectionTemp");
660 long loc = Locations.combine(((Token)get(0)).location, ((Token)get(length()-1)).location);
661 EVar symbol = (EVar)get(1);
662 return new ESimpleLambda(var,
663 new EApply(loc, symbol,
664 new EVariable(loc, var), (Expression)get(2)));
668 protected Object reduceLeftSection() {
669 return new EApply((EVar)get(2), (Expression)get(1));
673 protected Object reduceListLiteral() {
675 return new EListLiteral(Expression.EMPTY_ARRAY);
676 int dim = length()/2;
677 Expression[] components = new Expression[dim];
678 for(int i=0;i<dim;++i)
679 components[i] = (Expression)get(i*2+1);
680 return new EListLiteral(components);
684 protected Object reduceRange() {
692 protected Object reduceListComprehension() {
693 ListQualifier qualifier = (ListQualifier)get(3);
694 for(int i=5;i<length();i+=2) {
695 ListQualifier right = (ListQualifier)get(i);
696 if(right instanceof ListThen) {
697 ((ListThen) right).setLeft(qualifier);
701 qualifier = new ListSeq(qualifier, right);
703 return new EListComprehension((Expression)get(1), qualifier);
707 protected Object reduceAs() {
708 Token id = (Token)get(0);
709 return new EAsPattern(new EVar(id.location, id.text), (Expression)get(2));
713 protected Object reduceGuardedExpEq() {
714 Expression[] guards = new Expression[length()/2-1];
715 for(int i=0;i<guards.length;++i)
716 guards[i] = (Expression)get(i*2+1);
717 return new GuardedExpression(guards, (Expression)get(length()-1));
721 protected Object reduceLambda() {
722 Expression[] patterns = new Expression[length()-3];
723 for(int i=0;i<patterns.length;++i)
724 patterns[i] = (Expression)get(i+1);
725 Case case_ = new Case(patterns, (Expression)get(length()-1));
726 case_.setLhs(Locations.combine(patterns[0].location, patterns[patterns.length-1].location));
727 return new ELambda(case_);
731 protected Object reduceLambdaMatch() {
732 Case[] cases = new Case[length()/2-1];
733 for(int i=0;i<cases.length;++i)
734 cases[i] = (Case)get(i*2+2);
735 return new ELambda(cases);
739 protected Object reduceLet() {
740 EBlock block = (EBlock)get(1);
741 Expression expression = (Expression)get(3);
742 block.addStatement(new GuardStatement(expression));
743 Token letToken = (Token)get(0);
744 block.location = Locations.location(
745 Locations.beginOf(letToken.location),
746 Locations.endOf(expression.location));
751 protected Object reduceIf() {
755 length() == 6 ? (Expression)get(5) : null);
759 protected Object reduceMatch() {
760 Case[] cases = new Case[length()/2-2];
761 for(int i=0;i<cases.length;++i)
762 cases[i] = (Case)get(i*2+4);
763 return new EMatch((Expression)get(1), cases);
767 protected Object reduceDo() {
768 EBlock block = (EBlock)get(1);
769 Token doToken = (Token)get(0);
770 switch(doToken.text) {
772 block.setBlockType(BlockType.Monad);
775 block.setBlockType(BlockType.MonadE);
778 block.location = Locations.location(Locations.beginOf(doToken.location), Locations.endOf(block.location));
783 protected Object reduceSelect() {
784 return new ESelect(((Token)get(0)).id, (Expression)get(1), new QConjunction((Query[])get(3)));
788 protected Object reduceEnforce() {
789 return new EEnforce(new QConjunction((Query[])get(1)));
793 protected Object reduceApply() {
796 Expression[] parameters = new Expression[length()-1];
797 for(int i=0;i<parameters.length;++i)
798 parameters[i] = (Expression)get(i+1);
799 return new EApply((Expression)get(0), parameters);
803 protected Object reduceSymbol() {
804 return new EVar(((Token)get(0)).text);
808 protected Object reduceEscapedId() {
809 return new EVar(((Token)get(0)).text);
813 protected Object reduceMinus() {
814 return new EVar(((Token)get(0)).text);
818 protected Object reduceLess() {
819 return new EVar(((Token)get(0)).text);
823 protected Object reduceGreater() {
824 return new EVar(((Token)get(0)).text);
828 protected Object reduceDoubleLess() {
829 return new EVar(((Token)get(0)).text);
833 protected Object reduceDoubleGreater() {
834 return new EVar(((Token)get(0)).text);
838 protected Object reduceDot() {
839 return new EVar(((Token)get(0)).text);
843 protected Object reduceCase() {
844 return new Case((Expression)get(0), (Expression)get(1));
848 protected Object reduceGuardQualifier() {
849 return new ListGuard((Expression)get(0));
853 protected Object reduceLetQualifier() {
854 return new ListAssignment((Expression)get(0), (Expression)get(2));
858 protected Object reduceBindQualifier() {
859 return new ListGenerator((Expression)get(0), (Expression)get(2));
863 protected Object reduceThenQualifier() {
864 return new ListThen((Expression)get(1), length()==4 ? (Expression)get(3) : null);
868 protected Object reduceGuardStatement() {
869 return new GuardStatement((Expression)get(0));
873 protected Object reduceLetStatement() {
874 return new LetStatement((Expression)get(0), (Expression)get(1));
878 protected Object reduceBindStatement() {
879 return new BindStatement((Expression)get(0), (Expression)get(2));
883 protected Object reduceSimpleCaseRhs() {
888 protected Object reduceGuardedCaseRhs() {
889 GuardedExpression[] expressions = new GuardedExpression[length()];
890 for(int i=0;i<expressions.length;++i)
891 expressions[i] = (GuardedExpression)get(i);
892 return new GuardedExpressionGroup(expressions);
896 protected Object reduceGuardedExpArrow() {
897 Expression[] guards = new Expression[length()/2-1];
898 for(int i=0;i<guards.length;++i)
899 guards[i] = (Expression)get(i*2+1);
900 return new GuardedExpression(guards, (Expression)get(length()-1));
904 protected Object reduceEffect() {
905 ArrayList<TypeAst> effects = new ArrayList<TypeAst>(length()/2-1);
906 for(int i=1;i<length()-1;i+=2) {
907 Token token = (Token)get(i);
908 TVarAst ast = new TVarAst(token.text);
909 ast.location = token.location;
912 return new TEffectAst(effects, (TypeAst)get(length()-1));
916 protected Object reduceJustEtype() {
921 protected Object reduceForAll() {
922 String[] vars = new String[length()-3];
923 for(int i=0;i<vars.length;++i)
924 vars[i] = ((Token)get(i+1)).text;
925 return new TForAllAst(vars, (TypeAst)get(length()-1));
929 protected Object reduceApplyType() {
930 TypeAst[] parameters = new TypeAst[length()-1];
931 for(int i=0;i<parameters.length;++i)
932 parameters[i] = (TypeAst)get(i+1);
933 return new TApplyAst((TypeAst)get(0), parameters);
936 @SuppressWarnings("unchecked")
938 protected void postReduce(Object reduced) {
939 if(!(reduced instanceof Symbol))
941 Symbol sym = (Symbol)reduced;
942 if(sym.location != Locations.NO_LOCATION || length() == 0)
944 Object first = get(0);
945 if(!(first instanceof Symbol)) {
946 if(first instanceof List) {
947 List<Object> ll = (List<Object>)first;
951 Object[] ll = (Object[])first;
958 Object last = get(length()-1);
959 if(!(last instanceof Symbol)) {
960 if(last instanceof List) {
961 List<Object> ll = (List<Object>)last;
962 last = ll.get(ll.size()-1);
965 Object[] ll = (Object[])last;
967 last = ll[ll.length-1];
969 last = get(length()-2);
972 sym.location = (((Symbol)first).location & 0xffffffff00000000L)
973 | (((Symbol)last).location & 0xffffffffL);
974 /*for(int i=0;i<length();++i) {
976 System.out.print(obj.getClass().getSimpleName());
977 if(obj instanceof Token) {
978 Token t = (Token)obj;
979 System.out.print("(" + t.text + ")");
981 if(obj instanceof Symbol) {
982 Symbol s = (Symbol)obj;
983 System.out.print("["+ Locations.beginOf(s.location) + "-" + Locations.endOf(s.location) + "]");
985 System.out.print(" ");
987 System.out.println("-> " + reduced.getClass().getSimpleName() + " " +
988 Locations.beginOf(sym.location) + "-" + Locations.endOf(sym.location));*/
992 protected RuntimeException syntaxError(Token token, String description) {
993 throw new SCLSyntaxErrorException(token.location, description);
997 protected Object reduceIdAccessor() {
998 return new IdAccessor('.', ((Token)get(0)).text);
1002 protected Object reduceStringAccessor() {
1003 return new StringAccessor('.', ((Token)get(1)).text);
1007 protected Object reduceExpAccessor() {
1008 return new ExpressionAccessor('.', (Expression)get(1));
1012 protected Object reduceFieldAccess() {
1015 Expression result = (Expression)get(0);
1016 for(int i=2;i<length();i+=2) {
1017 FieldAccessor accessor = (FieldAccessor)get(i);
1018 accessor.accessSeparator = ((Token)get(i-1)).text.charAt(0);
1019 result = new EFieldAccess(result, accessor);
1025 protected Object reduceQueryBlock() {
1027 return Query.EMPTY_ARRAY;
1028 Query[] queries = new Query[length()/2];
1029 for(int i=0;i<queries.length;++i)
1030 queries[i] = (Query)get(2*i+1);
1035 protected Object reduceGuardQuery() {
1036 return new QPreGuard((Expression)get(0));
1040 protected Object reduceEqualsQuery() {
1041 return new QPreEquals((Expression)get(0), (Expression)get(2));
1045 protected Object reduceBindQuery() {
1046 return new QPreBinds((Expression)get(0), (Expression)get(2));
1050 protected Object reduceCompositeQuery() {
1051 Query[] queries = (Query[])get(1);
1052 switch(((Token)get(0)).text.charAt(1)) {
1053 case '&': return new QConjunction(queries);
1054 case '|': return new QDisjunction(queries);
1055 case '!': return new QNegation(new QConjunction(queries));
1056 case '?': return new QAlternative(queries);
1057 default: throw new InternalCompilerError();
1062 protected Object reduceRuleStatement() {
1063 return new RuleStatement((Expression)get(0), new QConjunction((Query[])get(2)));
1067 protected Object reduceHashedId() {
1068 return new EVar("#" + ((Token)get(1)).text);
1072 protected Object reduceStringLiteral() {
1073 int expCount = length()/3;
1075 return new ELiteral(new StringConstant(((Token)get(1)).text));
1077 String[] strings = new String[expCount+1];
1078 Expression[] expressions = new Expression[expCount];
1079 for(int i=0;i<expCount;++i) {
1080 strings[i] = ((Token)get(i*3+1)).text;
1081 expressions[i] = (Expression)get(i*3+2);
1083 strings[expCount] = ((Token)get(expCount*3+1)).text;
1084 return new EStringLiteral(strings, expressions);
1089 protected Object reduceOneCommand() {
1094 protected Object reduceManyCommands() {
1099 protected Object reduceStatementCommand() {
1100 // to be extended in subclasses
1105 protected Object reduceImportCommand() {
1106 // to be extended in subclasses
1111 protected Object reduceImportValueItem() {
1112 return new EVar(((Token)get(0)).text);
1116 protected Object reduceImportHiding() {
1117 EVar[] values = new EVar[(length()-2)/2];
1118 for(int i=0;i<values.length;++i)
1119 values[i] = (EVar)get(i*2+2);
1120 return new ImportDeclaration.ImportSpec(true, values);
1124 protected Object reduceImportShowing() {
1125 EVar[] values = new EVar[(length()-1)/2];
1126 for(int i=0;i<values.length;++i)
1127 values[i] = (EVar)get(i*2+1);
1128 return new ImportDeclaration.ImportSpec(false, values);
1132 protected Object reduceRuleDeclarations() {
1133 ArrayList<Object> declarations = new ArrayList<Object>(length()/2);
1134 for(int i=1;i<length();i+=2)
1135 declarations.add((Object)get(i));
1136 return declarations;
1139 private static final String[] EMPTY_STRING_ARRAY = new String[0];
1141 @SuppressWarnings("unchecked")
1143 protected Object reduceRuleDefinition() {
1144 String[] extendsNames = EMPTY_STRING_ARRAY;
1146 int extendsCount = (length() - 4) / 2;
1147 extendsNames = new String[extendsCount];
1148 for(int i=0;i<extendsCount;++i)
1149 extendsNames[i] = ((Token)get(3+i*2)).text;
1152 DRuleAst rule = new DRuleAst(
1153 ((Token)get(0)).id == SCLTerminals.ABSTRACT_RULE,
1154 ((Token)get(1)).text,
1157 ArrayList<Object> ruleDeclarations = (ArrayList<Object>)get(length()-1);
1158 ArrayList<Query> section = null;
1159 for(Object decl : ruleDeclarations) {
1160 if(decl instanceof DAnnotationAst) {
1161 DAnnotationAst annotation = (DAnnotationAst)decl;
1162 section = rule.getSection(annotation.id.text.substring(1));
1164 else if(decl instanceof Query) {
1166 section = rule.getSection("when");
1167 section.add((Query)decl);
1170 throw new InternalCompilerError();
1176 protected Object reduceQueryRuleDeclaration() {
1181 protected Object reduceMappingRelationDefinition() {
1182 TypeAst[] types = new TypeAst[length()-2];
1183 for(int i=0;i<types.length;++i)
1184 types[i] = (TypeAst)get(i+2);
1185 return new DMappingRelationAst(
1186 ((Token)get(1)).text,
1191 protected Object reduceTransformation() {
1192 return new ETransformation(
1193 ((Token)get(1)).text,
1194 new QConjunction((Query[])get(3))
1198 @SuppressWarnings("unchecked")
1200 protected Object reduceRelationDefinition() {
1201 return new DRelationAst((Expression)get(0),
1202 ((ArrayList<Object>)get(2)).toArray());
1206 protected Object reduceRecord() {
1207 FieldAssignment[] fields = new FieldAssignment[length()/2-1];
1208 for(int i=0;i<fields.length;++i)
1209 fields[i] = (FieldAssignment)get(2+i*2);
1210 return new ERecord(new EVar((Token)get(0)), fields);
1214 protected Object reduceField() {
1215 return new FieldAssignment(((Token)get(0)).text, (Expression)get(2));
1219 protected Object reduceFieldShorthand() {
1220 return new FieldAssignment(((Token)get(0)).text, null);
1224 protected Object reduceRecordConstructor() {
1226 for(idPos=0;idPos<length();idPos+=2)
1227 if(((Token)get(idPos)).id == SCLTerminals.ID)
1229 DAnnotationAst[] annotations = idPos == 0 ? DAnnotationAst.EMPTY_ARRAY : new DAnnotationAst[idPos/2];
1230 for(int i=0;i<idPos/2;++i)
1231 annotations[i] = new DAnnotationAst((Token)get(i*2),
1232 Arrays.asList((Expression)get(i*2+1)));
1233 TypeAst[] parameters = new TypeAst[(length()-idPos-1)/2];
1234 String[] fieldNames = new String[parameters.length];
1235 for(int i=0;i<parameters.length;++i) {
1236 FieldDescription fieldDesc = (FieldDescription)get(idPos+(i+1)*2);
1237 parameters[i] = fieldDesc.type;
1238 fieldNames[i] = fieldDesc.name;
1240 return new ConstructorAst(annotations, (Token)get(idPos), parameters, fieldNames);
1244 protected Object reduceFieldDescription() {
1245 return new FieldDescription(((Token)get(0)).text, (TypeAst)get(2));
1249 protected Object reduceEq() {
1250 return (Expression)get(2);
1254 protected Object reduceEquationBlock() {
1256 return new EEquations(Equation.EMPTY_ARRAY);
1257 Equation[] equations = new Equation[length()/2+1];
1258 for(int i=0;i<equations.length;++i)
1259 equations[i] = (Equation)get(2*i);
1260 return new EEquations(equations);
1264 protected Object reduceGuardEquation() {
1265 return new EqGuard((Expression)get(0));
1269 protected Object reduceBasicEquation() {
1270 return new EqBasic((Expression)get(0), (Expression)get(2));
1274 protected Object reduceViewPattern() {
1275 return new EViewPattern((Expression)get(1), (Expression)get(3));
1279 protected Object reduceConstraintStatement() {
1280 ConstructorAst constructor = (ConstructorAst)get(1);
1281 return new ConstraintStatement(constructor.name, constructor.parameters, constructor.fieldNames, constructor.annotations);
1286 protected Object reduceWhen() {
1288 new QConjunction((Query[])get(1)),
1289 (Expression)get(3));
1293 protected Object reduceDummy() {
1294 throw new UnsupportedOperationException();
1298 protected Object reduceRulesetDefinition() {
1299 Token name = (Token)get(1);
1300 EBlock block = (EBlock)get(3);
1301 return new DRulesetAst(name.text, block);
1305 protected Object reduceLocalInclude() {
1306 Token name = (Token)get(1);
1307 Expression value = (Expression)get(2);
1308 return new IncludeStatement(name, value);
1312 protected Object reduceConstraintSpec() {
1313 Expression[] expressions = new Expression[length()/2-1];
1314 for(int i=0;i<expressions.length;++i)
1315 expressions[i] = (Expression)get(2*i+1);
1320 protected Object reduceCHRSelect() {
1321 return new EPreCHRSelect((CHRAstQuery)get(3), (Expression)get(1));
1325 protected Object reduceCHRAtom() {
1326 return CHRAstAtom.atom((Expression)get(0));
1330 protected Object reduceCHREquals() {
1331 return new CHRAstEquals((Expression)get(0), (Expression)get(2));
1335 protected Object reduceCHRBinds() {
1336 return new CHRAstBinds((Expression)get(0), (Expression)get(2));
1340 protected Object reduceCHRConjunction() {
1341 CHRAstQuery[] conjuncts = new CHRAstQuery[(length()+1)/2];
1342 for(int i=0;i<conjuncts.length;++i)
1343 conjuncts[i] = (CHRAstQuery)get(i*2);
1344 return CHRAstConjunction.conjunction(conjuncts);
1348 protected Object reduceVerboseCHRConjunction() {
1349 CHRAstQuery[] conjuncts = new CHRAstQuery[(length()-1)/2];
1350 for(int i=0;i<conjuncts.length;++i)
1351 conjuncts[i] = (CHRAstQuery)get(i*2+1);
1352 return CHRAstConjunction.conjunction(conjuncts);
1356 protected Object reduceVerboseCHRStatement() {
1357 return new CHRStatement((CHRAstQuery)get(1), (CHRAstQuery)get(3));
1361 protected Object reduceCHRStatement() {
1362 return new CHRStatement((CHRAstQuery)get(0), (CHRAstQuery)get(2));
1366 protected Object reduceWildcard() {
1367 return new FieldAssignment(FieldAssignment.WILDCARD, null);
1371 protected Object reducePlainEffect() {
1372 ArrayList<TypeAst> effects = new ArrayList<TypeAst>(length()/2);
1373 for(int i=1;i<length();i+=2) {
1374 Token token = (Token)get(i);
1375 TVarAst ast = new TVarAst(token.text);
1376 ast.location = token.location;
1379 return new TPlainEffectAst(effects);