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.CHRStatement;
61 import org.simantics.scl.compiler.elaboration.expressions.block.ConstraintStatement;
62 import org.simantics.scl.compiler.elaboration.expressions.block.GuardStatement;
63 import org.simantics.scl.compiler.elaboration.expressions.block.IncludeStatement;
64 import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement;
65 import org.simantics.scl.compiler.elaboration.expressions.block.RuleStatement;
66 import org.simantics.scl.compiler.elaboration.expressions.block.Statement;
67 import org.simantics.scl.compiler.elaboration.expressions.list.ListAssignment;
68 import org.simantics.scl.compiler.elaboration.expressions.list.ListGenerator;
69 import org.simantics.scl.compiler.elaboration.expressions.list.ListGuard;
70 import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifier;
71 import org.simantics.scl.compiler.elaboration.expressions.list.ListSeq;
72 import org.simantics.scl.compiler.elaboration.expressions.list.ListThen;
73 import org.simantics.scl.compiler.elaboration.expressions.records.FieldAssignment;
74 import org.simantics.scl.compiler.elaboration.java.Builtins;
75 import org.simantics.scl.compiler.elaboration.query.QAlternative;
76 import org.simantics.scl.compiler.elaboration.query.QConjunction;
77 import org.simantics.scl.compiler.elaboration.query.QDisjunction;
78 import org.simantics.scl.compiler.elaboration.query.QNegation;
79 import org.simantics.scl.compiler.elaboration.query.Query;
80 import org.simantics.scl.compiler.elaboration.query.pre.QPreBinds;
81 import org.simantics.scl.compiler.elaboration.query.pre.QPreEquals;
82 import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard;
83 import org.simantics.scl.compiler.errors.Locations;
84 import org.simantics.scl.compiler.internal.header.ModuleHeader;
85 import org.simantics.scl.compiler.internal.parsing.Symbol;
86 import org.simantics.scl.compiler.internal.parsing.Token;
87 import org.simantics.scl.compiler.internal.parsing.declarations.ConstructorAst;
88 import org.simantics.scl.compiler.internal.parsing.declarations.DAnnotationAst;
89 import org.simantics.scl.compiler.internal.parsing.declarations.DClassAst;
90 import org.simantics.scl.compiler.internal.parsing.declarations.DDataAst;
91 import org.simantics.scl.compiler.internal.parsing.declarations.DDerivingInstanceAst;
92 import org.simantics.scl.compiler.internal.parsing.declarations.DDocumentationAst;
93 import org.simantics.scl.compiler.internal.parsing.declarations.DEffectAst;
94 import org.simantics.scl.compiler.internal.parsing.declarations.DFixityAst;
95 import org.simantics.scl.compiler.internal.parsing.declarations.DImportJavaAst;
96 import org.simantics.scl.compiler.internal.parsing.declarations.DInstanceAst;
97 import org.simantics.scl.compiler.internal.parsing.declarations.DMappingRelationAst;
98 import org.simantics.scl.compiler.internal.parsing.declarations.DRelationAst;
99 import org.simantics.scl.compiler.internal.parsing.declarations.DRuleAst;
100 import org.simantics.scl.compiler.internal.parsing.declarations.DRulesetAst;
101 import org.simantics.scl.compiler.internal.parsing.declarations.DTypeAst;
102 import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst;
103 import org.simantics.scl.compiler.internal.parsing.declarations.DValueTypeAst;
104 import org.simantics.scl.compiler.internal.parsing.declarations.DeclarationAst;
105 import org.simantics.scl.compiler.internal.parsing.declarations.FieldDescription;
106 import org.simantics.scl.compiler.internal.parsing.declarations.FundepAst;
107 import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
108 import org.simantics.scl.compiler.internal.parsing.types.TApplyAst;
109 import org.simantics.scl.compiler.internal.parsing.types.TEffectAst;
110 import org.simantics.scl.compiler.internal.parsing.types.TForAllAst;
111 import org.simantics.scl.compiler.internal.parsing.types.TFunctionAst;
112 import org.simantics.scl.compiler.internal.parsing.types.TListAst;
113 import org.simantics.scl.compiler.internal.parsing.types.TPredAst;
114 import org.simantics.scl.compiler.internal.parsing.types.TTupleAst;
115 import org.simantics.scl.compiler.internal.parsing.types.TVarAst;
116 import org.simantics.scl.compiler.internal.parsing.types.TypeAst;
117 import org.simantics.scl.compiler.module.ImportDeclaration;
118 import org.simantics.scl.compiler.types.Types;
121 public class SCLParserImpl extends SCLParser {
123 private final SCLPostLexer lexer;
124 private SCLParserOptions options;
125 private CompilationContext context;
127 public SCLParserImpl(Reader reader) {
128 this.lexer = new SCLPostLexer(reader);
131 public void setCompilationContext(CompilationContext context) {
132 this.context = context;
133 lexer.setCompilationContext(context);
136 public void setParserOptions(SCLParserOptions options) {
137 this.options = options;
138 lexer.setParserOptions(options);
141 public boolean isEmpty() throws Exception {
142 return lexer.peekToken().id == SCLTerminals.EOF;
146 protected Token nextToken() {
148 Token token = lexer.nextToken();
149 /*System.out.println("TOKEN " + token.text + " (" + TERMINAL_NAMES[token.id] + ")" +
151 + Locations.beginOf(token.location) + ".."
152 + Locations.endOf(token.location) + "]");*/
154 } catch(Exception e) {
155 if(e instanceof RuntimeException)
156 throw (RuntimeException)e;
158 throw new RuntimeException(e);
163 protected Object reduceDeclarations() {
164 ArrayList<DeclarationAst> declarations = new ArrayList<DeclarationAst>(length()/2);
165 for(int i=1;i<length();i+=2)
166 declarations.add((DeclarationAst)get(i));
171 protected Object reduceModule() {
172 ArrayList<DeclarationAst> declarations = new ArrayList<DeclarationAst>(length()/2+1);
173 for(int i=0;i<length();i+=2) {
174 DeclarationAst declaration = (DeclarationAst)get(i);
175 if(declaration == null)
177 declarations.add(declaration);
183 protected Object reduceModuleHeader() {
184 FieldAssignment[] fields = new FieldAssignment[length()/2-1];
185 for(int i=0;i<fields.length;++i)
186 fields[i] = (FieldAssignment)get(2+i*2);
187 context.header = ModuleHeader.process(context.errorLog, fields);
192 protected Object reduceLocalTypeAnnotation() {
195 return new ETypeAnnotation((Expression)get(0), (TypeAst)get(2));
199 protected Object reduceTypeAnnotation() {
200 EVar[] names = new EVar[length()/2];
201 for(int i=0;i<names.length;++i)
202 names[i] = (EVar)get(i*2);
203 return new DValueTypeAst(
205 (TypeAst)get(length()-1)
210 protected Object reduceValueDefinition() {
211 Expression rhs = (Expression)get(1);
212 return new DValueAst((Expression)get(0), rhs);
216 protected Object reduceDataDefinition() {
218 ArrayList<String> parameters = new ArrayList<String>();
219 while(i < length()) {
220 Token token = (Token)get(i++);
221 if(token.id != SCLTerminals.ID)
223 parameters.add(token.text);
225 ArrayList<ConstructorAst> constructors = new ArrayList<ConstructorAst>();
226 for(;i < length();i+=2)
227 constructors.add((ConstructorAst)get(i));
229 ((Token)get(1)).text,
230 parameters.toArray(new String[parameters.size()]),
231 constructors.toArray(new ConstructorAst[constructors.size()]),
237 protected Object reduceTypeDefinition() {
239 ArrayList<String> parameters = new ArrayList<String>();
241 Token token = (Token)get(i++);
242 if(token.id != SCLTerminals.ID)
244 parameters.add(token.text);
247 ((Token)get(1)).text,
248 parameters.toArray(new String[parameters.size()]),
253 @SuppressWarnings("unchecked")
255 protected Object reduceClassDefinition() {
257 ArrayList<TypeAst> context;
258 if(get(i) instanceof Token)
259 context = new ArrayList<TypeAst>(0);
261 context = (ArrayList<TypeAst>)get(i++);
262 String name = ((Token)get(i++)).text;
263 ArrayList<String> parameters = new ArrayList<String>();
264 while(i < length()) {
265 Token token = (Token)get(i);
266 if(token.id != SCLTerminals.ID)
268 parameters.add(token.text);
271 ArrayList<DeclarationAst> declarations = null;
272 FundepAst[] fundeps = FundepAst.EMPTY_ARRAY;
273 while(i < length()) {
274 Token token = (Token)get(i++);
275 if(token.id == SCLTerminals.WHERE) {
276 declarations = (ArrayList<DeclarationAst>)get(i++);
278 else if(token.id == SCLTerminals.BAR) {
279 fundeps = (FundepAst[])get(i++);
282 throw new InternalCompilerError();
284 return new DClassAst(context, name,
285 parameters.toArray(new String[parameters.size()]),
291 protected Object reduceFundep() {
292 String[] from = new String[length()-2];
293 for(int i=0;i<from.length;++i)
294 from[i] = ((Token)get(i)).text;
295 String to = ((Token)get(length()-1)).text;
296 return new FundepAst(from, to);
300 protected Object reduceFundeps() {
301 FundepAst[] fundeps = new FundepAst[(length()+1)/2];
302 for(int i=0;i<fundeps.length;++i)
303 fundeps[i] = (FundepAst)get(i*2);
307 @SuppressWarnings("unchecked")
309 protected Object reduceInstanceDefinition() {
311 ArrayList<TypeAst> context;
312 if(get(i) instanceof Token)
313 context = new ArrayList<TypeAst>(0);
315 context = (ArrayList<TypeAst>)get(i++);
316 Token nameToken = (Token)get(i++);
317 EVar name = new EVar(nameToken);
318 ArrayList<TypeAst> parameters = new ArrayList<TypeAst>();
319 while(i < length()) {
320 Object symbol = get(i++);
321 if(symbol instanceof Token)
323 parameters.add((TypeAst)symbol);
325 ArrayList<DeclarationAst> declarations = null;
327 declarations = (ArrayList<DeclarationAst>)get(i);
328 return new DInstanceAst(context, name,
329 parameters.toArray(new TypeAst[parameters.size()]),
333 @SuppressWarnings("unchecked")
335 protected Object reduceDerivingInstanceDefinition() {
337 ArrayList<TypeAst> context;
338 if(get(i) instanceof Token)
339 context = new ArrayList<TypeAst>(0);
341 context = (ArrayList<TypeAst>)get(i++);
342 Token nameToken = (Token)get(i++);
343 EVar name = new EVar(nameToken);
344 ArrayList<TypeAst> parameters = new ArrayList<TypeAst>();
345 while(i < length()) {
346 Object symbol = get(i++);
347 parameters.add((TypeAst)symbol);
349 return new DDerivingInstanceAst(context, name,
350 parameters.toArray(new TypeAst[parameters.size()]));
354 protected Object reduceDocumentationString() {
355 return new DDocumentationAst(((Token)get(1)).text);
359 protected Object reduceAnnotation() {
360 ArrayList<Expression> parameters = new ArrayList<Expression>(length()-1);
361 for(int i=1;i<length();++i)
362 parameters.add((Expression)get(i));
363 return new DAnnotationAst((Token)get(0), parameters);
367 protected Object reducePrecedenceDefinition() {
368 EVar[] symbols = new EVar[length()/2];
369 for(int i=0;i<symbols.length;++i)
370 symbols[i] = (EVar)get(2*i + 2);
371 Associativity associativity;
372 Token token = (Token)get(0);
373 if(token.text.equals("infixl"))
374 associativity = Associativity.LEFT;
375 else if(token.text.equals("infixr"))
376 associativity = Associativity.RIGHT;
378 associativity = Associativity.NONASSOC;
379 return new DFixityAst(
381 Integer.parseInt(((Token)get(1)).text),
387 protected Object reduceImport() {
388 // (AS ID)? importSpec?
390 String importKeyword = ((Token)get(pos++)).text; // (IMPORT | INCLUDE)
391 ++pos; // BEGIN_STRING
392 String moduleName = ((Token)get(pos++)).text; // END_STRING
393 String localName = "";
395 Object temp = get(pos);
396 if(temp instanceof Token) {
397 Token token = (Token)temp;
398 if(token.id == SCLTerminals.AS) {
400 localName = ((Token)get(pos++)).text; // ID
404 ImportDeclaration.ImportSpec spec = ImportDeclaration.DEFAULT_SPEC;
406 spec = (ImportDeclaration.ImportSpec)get(pos++);
407 return new ImportDeclaration(moduleName, localName,
408 importKeyword.equals("include"),
413 protected Object reduceJustImport() {
417 @SuppressWarnings("unchecked")
419 protected Object reduceImportJava() {
420 return new DImportJavaAst(((Token)get(2)).text, (ArrayList<DeclarationAst>)get(4));
424 protected Object reduceEffectDefinition() {
425 return new DEffectAst(
426 ((Token)get(1)).text,
427 ((Token)get(3)).text,
428 ((Token)get(5)).text);
432 protected Object reduceVarId() {
433 return new EVar((Token)get(0));
437 protected Object reduceEscapedSymbol() {
438 return new EVar((Token)get(0));
442 protected Object reduceTupleTypeConstructor() {
443 return new TVarAst(Types.tupleConstructor(length()-1).name);
447 protected Object reduceArrow() {
449 TypeAst result = (TypeAst)get(i);
452 if( ((Token)get(i+1)).text.equals("=>") )
453 result = new TPredAst((TypeAst)get(i), result);
455 result = new TFunctionAst((TypeAst)get(i), result);
462 protected Object reduceBinary() {
466 EVar negation = null;
467 if(get(i) instanceof Token) {
468 Token token = (Token)get(i++);
469 negation = new EVar(token);
471 EBinary binary = new EBinary((Expression)get(i++), negation);
472 while(i < length()) {
473 EVar operator = (EVar)get(i++);
474 Expression right = (Expression)get(i++);
475 binary.rights.add(new EBinaryRightSide(operator, right));
481 protected Object reduceSimpleRhs() {
485 EBlock block = (EBlock)get(3);
486 Expression expression = (Expression)get(1);
487 block.addStatement(new GuardStatement(expression));
488 block.location = Locations.location(Locations.beginOf(expression.location), Locations.endOf(block.location));
493 private GuardedExpressionGroup reduceGuardedExpressionGroup(int length) {
494 GuardedExpression[] expressions = new GuardedExpression[length];
495 for(int i=0;i<expressions.length;++i) {
496 expressions[i] = (GuardedExpression)get(i);
498 return new GuardedExpressionGroup(expressions);
502 protected Object reduceGuardedRhs() {
503 int length = length();
504 if(length > 2 && get(length-2) instanceof Token) {
505 EBlock block = (EBlock)get(length-1);
506 block.addStatement(new GuardStatement(reduceGuardedExpressionGroup(length-2)));
507 block.location = Locations.NO_LOCATION;
511 return reduceGuardedExpressionGroup(length);
515 protected Object reduceStatements() {
516 EBlock block = new EBlock();
518 for(int i=1;i<length();i+=2)
519 block.addStatement((Statement)get(i));
524 protected Object reduceConstructor() {
526 for(idPos=0;idPos<length();idPos+=2)
527 if(((Token)get(idPos)).id == SCLTerminals.ID)
529 DAnnotationAst[] annotations = idPos == 0 ? DAnnotationAst.EMPTY_ARRAY : new DAnnotationAst[idPos/2];
530 for(int i=0;i<idPos/2;++i)
531 annotations[i] = new DAnnotationAst((Token)get(i*2),
532 Arrays.asList((Expression)get(i*2+1)));
533 TypeAst[] parameters = new TypeAst[length()-idPos-1];
534 for(int i=0;i<parameters.length;++i)
535 parameters[i] = (TypeAst)get(i+idPos+1);
536 return new ConstructorAst(annotations, (Token)get(idPos), parameters, null);
540 protected Object reduceContext() {
541 ArrayList<TypeAst> result = new ArrayList<TypeAst>(length()/2-1);
542 for(int i=1;i<length()-2;i+=2)
543 result.add((TypeAst)get(i));
548 protected Object reduceTypeVar() {
549 return new TVarAst(((Token)get(0)).text);
553 protected Object reduceTupleType() {
555 return new TTupleAst(TypeAst.EMPTY_ARRAY);
557 Symbol sym = (Symbol)get(1);
558 sym.location = Locations.NO_LOCATION;
561 int dim = length()/2;
562 TypeAst[] parameters = new TypeAst[dim];
563 for(int i=0;i<dim;++i)
564 parameters[i] = (TypeAst)get(i*2+1);
565 return new TTupleAst(parameters);
569 protected Object reduceListType() {
570 return new TListAst((TypeAst)get(1));
574 protected Object reduceListTypeConstructor() {
575 return new TVarAst("[]");
579 protected Object reduceTupleConstructor() {
580 return new EVar(Types.tupleConstructor(length()-1).name);
584 protected Object reduceVar() {
589 protected Object reduceBlank() {
590 return new EVar(((Token)get(0)).location, "_");
594 protected Object reduceInteger() {
595 return new EIntegerLiteral(((Token)get(0)).text);
599 protected Object reduceFloat() {
600 return new ERealLiteral(((Token)get(0)).text);
604 protected Object reduceString() {
609 protected Object reduceChar() {
610 String text = ((Token)get(0)).text;
611 char c = text.charAt(text.length()-2);
612 if(text.length() == 4) {
614 case 'n': c = '\n'; break;
615 case 't': c = '\t'; break;
616 case 'b': c = '\b'; break;
617 case 'f': c = '\f'; break;
618 case 'r': c = '\r'; break;
621 return new ELiteral(new CharacterConstant(c));
625 protected Object reduceTuple() {
627 return new EConstant(Builtins.TUPLE_CONSTRUCTORS[0]);
629 Symbol sym = (Symbol)get(1);
630 sym.location = Locations.NO_LOCATION;
633 int dim = length()/2;
634 Expression[] parameters = new Expression[dim];
635 for(int i=0;i<dim;++i)
636 parameters[i] = (Expression)get(i*2+1);
637 EConstant tupleConstructor = new EConstant(Builtins.TUPLE_CONSTRUCTORS[dim]);
638 tupleConstructor.location = Locations.location(
639 Locations.beginOf(((Token)get(0)).location),
640 Locations.endOf(((Token)get(length()-1)).location));
641 return new EApply(tupleConstructor, parameters);
644 public static Expression rightSection(EVar op, Expression e) {
645 long loc = Locations.combine(op.location, e.location);
646 Variable var = new Variable("rightSectionTemp");
647 return new ESimpleLambda(loc, var,
648 new EApply(loc, op, new EVariable(loc, var), e));
652 protected Object reduceRightSection() {
653 Variable var = new Variable("rightSectionTemp");
654 long loc = Locations.combine(((Token)get(0)).location, ((Token)get(length()-1)).location);
655 EVar symbol = (EVar)get(1);
656 return new ESimpleLambda(var,
657 new EApply(loc, symbol,
658 new EVariable(loc, var), (Expression)get(2)));
662 protected Object reduceLeftSection() {
663 return new EApply((EVar)get(2), (Expression)get(1));
667 protected Object reduceListLiteral() {
669 return new EListLiteral(Expression.EMPTY_ARRAY);
670 int dim = length()/2;
671 Expression[] components = new Expression[dim];
672 for(int i=0;i<dim;++i)
673 components[i] = (Expression)get(i*2+1);
674 return new EListLiteral(components);
678 protected Object reduceRange() {
686 protected Object reduceListComprehension() {
687 ListQualifier qualifier = (ListQualifier)get(3);
688 for(int i=5;i<length();i+=2) {
689 ListQualifier right = (ListQualifier)get(i);
690 if(right instanceof ListThen) {
691 ((ListThen) right).setLeft(qualifier);
695 qualifier = new ListSeq(qualifier, right);
697 return new EListComprehension((Expression)get(1), qualifier);
701 protected Object reduceAs() {
702 Token id = (Token)get(0);
703 return new EAsPattern(new EVar(id.location, id.text), (Expression)get(2));
707 protected Object reduceGuardedExpEq() {
708 Expression[] guards = new Expression[length()/2-1];
709 for(int i=0;i<guards.length;++i)
710 guards[i] = (Expression)get(i*2+1);
711 return new GuardedExpression(guards, (Expression)get(length()-1));
715 protected Object reduceLambda() {
716 Expression[] patterns = new Expression[length()-3];
717 for(int i=0;i<patterns.length;++i)
718 patterns[i] = (Expression)get(i+1);
719 Case case_ = new Case(patterns, (Expression)get(length()-1));
720 case_.setLhs(Locations.combine(patterns[0].location, patterns[patterns.length-1].location));
721 return new ELambda(case_);
725 protected Object reduceLambdaMatch() {
726 Case[] cases = new Case[length()/2-1];
727 for(int i=0;i<cases.length;++i)
728 cases[i] = (Case)get(i*2+2);
729 return new ELambda(cases);
733 protected Object reduceLet() {
734 EBlock block = (EBlock)get(1);
735 Expression expression = (Expression)get(3);
736 block.addStatement(new GuardStatement(expression));
737 Token letToken = (Token)get(0);
738 block.location = Locations.location(
739 Locations.beginOf(letToken.location),
740 Locations.endOf(expression.location));
745 protected Object reduceIf() {
749 length() == 6 ? (Expression)get(5) : null);
753 protected Object reduceMatch() {
754 Case[] cases = new Case[length()/2-2];
755 for(int i=0;i<cases.length;++i)
756 cases[i] = (Case)get(i*2+4);
757 return new EMatch((Expression)get(1), cases);
761 protected Object reduceDo() {
762 EBlock block = (EBlock)get(1);
763 Token doToken = (Token)get(0);
764 block.setMonadic( doToken.text.equals("mdo") );
765 block.location = Locations.location(Locations.beginOf(doToken.location), Locations.endOf(block.location));
770 protected Object reduceSelect() {
771 return new ESelect(((Token)get(0)).id, (Expression)get(1), new QConjunction((Query[])get(3)));
775 protected Object reduceEnforce() {
776 return new EEnforce(new QConjunction((Query[])get(1)));
780 protected Object reduceApply() {
783 Expression[] parameters = new Expression[length()-1];
784 for(int i=0;i<parameters.length;++i)
785 parameters[i] = (Expression)get(i+1);
786 return new EApply((Expression)get(0), parameters);
790 protected Object reduceSymbol() {
791 return new EVar(((Token)get(0)).text);
795 protected Object reduceEscapedId() {
796 return new EVar(((Token)get(0)).text);
800 protected Object reduceMinus() {
801 return new EVar(((Token)get(0)).text);
805 protected Object reduceLess() {
806 return new EVar(((Token)get(0)).text);
810 protected Object reduceGreater() {
811 return new EVar(((Token)get(0)).text);
815 protected Object reduceDot() {
816 return new EVar(((Token)get(0)).text);
820 protected Object reduceCase() {
821 return new Case((Expression)get(0), (Expression)get(1));
825 protected Object reduceGuardQualifier() {
826 return new ListGuard((Expression)get(0));
830 protected Object reduceLetQualifier() {
831 return new ListAssignment((Expression)get(0), (Expression)get(2));
835 protected Object reduceBindQualifier() {
836 return new ListGenerator((Expression)get(0), (Expression)get(2));
840 protected Object reduceThenQualifier() {
841 return new ListThen((Expression)get(1), length()==4 ? (Expression)get(3) : null);
845 protected Object reduceGuardStatement() {
846 return new GuardStatement((Expression)get(0));
850 protected Object reduceLetStatement() {
851 return new LetStatement((Expression)get(0), (Expression)get(1));
855 protected Object reduceBindStatement() {
856 return new BindStatement((Expression)get(0), (Expression)get(2));
860 protected Object reduceSimpleCaseRhs() {
865 protected Object reduceGuardedCaseRhs() {
866 GuardedExpression[] expressions = new GuardedExpression[length()];
867 for(int i=0;i<expressions.length;++i)
868 expressions[i] = (GuardedExpression)get(i);
869 return new GuardedExpressionGroup(expressions);
873 protected Object reduceGuardedExpArrow() {
874 Expression[] guards = new Expression[length()/2-1];
875 for(int i=0;i<guards.length;++i)
876 guards[i] = (Expression)get(i*2+1);
877 return new GuardedExpression(guards, (Expression)get(length()-1));
881 protected Object reduceEffect() {
882 ArrayList<TypeAst> effects = new ArrayList<TypeAst>(length()/2-1);
883 for(int i=1;i<length()-1;i+=2) {
884 Token token = (Token)get(i);
885 TVarAst ast = new TVarAst(token.text);
886 ast.location = token.location;
889 return new TEffectAst(effects, (TypeAst)get(length()-1));
893 protected Object reduceJustEtype() {
898 protected Object reduceForAll() {
899 String[] vars = new String[length()-3];
900 for(int i=0;i<vars.length;++i)
901 vars[i] = ((Token)get(i+1)).text;
902 return new TForAllAst(vars, (TypeAst)get(length()-1));
906 protected Object reduceApplyType() {
907 TypeAst[] parameters = new TypeAst[length()-1];
908 for(int i=0;i<parameters.length;++i)
909 parameters[i] = (TypeAst)get(i+1);
910 return new TApplyAst((TypeAst)get(0), parameters);
913 @SuppressWarnings("unchecked")
915 protected void postReduce(Object reduced) {
916 if(!(reduced instanceof Symbol))
918 Symbol sym = (Symbol)reduced;
919 if(sym.location != Locations.NO_LOCATION || length() == 0)
921 Object first = get(0);
922 if(!(first instanceof Symbol)) {
923 if(first instanceof List) {
924 List<Object> ll = (List<Object>)first;
928 Object[] ll = (Object[])first;
935 Object last = get(length()-1);
936 if(!(last instanceof Symbol)) {
937 if(last instanceof List) {
938 List<Object> ll = (List<Object>)last;
939 last = ll.get(ll.size()-1);
942 Object[] ll = (Object[])last;
944 last = ll[ll.length-1];
946 last = get(length()-2);
949 sym.location = (((Symbol)first).location & 0xffffffff00000000L)
950 | (((Symbol)last).location & 0xffffffffL);
951 /*for(int i=0;i<length();++i) {
953 System.out.print(obj.getClass().getSimpleName());
954 if(obj instanceof Token) {
955 Token t = (Token)obj;
956 System.out.print("(" + t.text + ")");
958 if(obj instanceof Symbol) {
959 Symbol s = (Symbol)obj;
960 System.out.print("["+ Locations.beginOf(s.location) + "-" + Locations.endOf(s.location) + "]");
962 System.out.print(" ");
964 System.out.println("-> " + reduced.getClass().getSimpleName() + " " +
965 Locations.beginOf(sym.location) + "-" + Locations.endOf(sym.location));*/
969 protected RuntimeException syntaxError(Token token, String description) {
970 throw new SCLSyntaxErrorException(token.location, description);
974 protected Object reduceIdAccessor() {
975 return new IdAccessor('.', ((Token)get(0)).text);
979 protected Object reduceStringAccessor() {
980 return new StringAccessor('.', ((Token)get(1)).text);
984 protected Object reduceExpAccessor() {
985 return new ExpressionAccessor('.', (Expression)get(1));
989 protected Object reduceFieldAccess() {
992 Expression result = (Expression)get(0);
993 for(int i=2;i<length();i+=2) {
994 FieldAccessor accessor = (FieldAccessor)get(i);
995 accessor.accessSeparator = ((Token)get(i-1)).text.charAt(0);
996 result = new EFieldAccess(result, accessor);
1002 protected Object reduceQueryBlock() {
1004 return Query.EMPTY_ARRAY;
1005 Query[] queries = new Query[length()/2];
1006 for(int i=0;i<queries.length;++i)
1007 queries[i] = (Query)get(2*i+1);
1012 protected Object reduceGuardQuery() {
1013 return new QPreGuard((Expression)get(0));
1017 protected Object reduceEqualsQuery() {
1018 return new QPreEquals((Expression)get(0), (Expression)get(2));
1022 protected Object reduceBindQuery() {
1023 return new QPreBinds((Expression)get(0), (Expression)get(2));
1027 protected Object reduceCompositeQuery() {
1028 Query[] queries = (Query[])get(1);
1029 switch(((Token)get(0)).text.charAt(1)) {
1030 case '&': return new QConjunction(queries);
1031 case '|': return new QDisjunction(queries);
1032 case '!': return new QNegation(new QConjunction(queries));
1033 case '?': return new QAlternative(queries);
1034 default: throw new InternalCompilerError();
1039 protected Object reduceRuleStatement() {
1040 return new RuleStatement((Expression)get(0), new QConjunction((Query[])get(2)));
1044 protected Object reduceHashedId() {
1045 return new EVar("#" + ((Token)get(1)).text);
1049 protected Object reduceStringLiteral() {
1050 int expCount = length()/3;
1052 return new ELiteral(new StringConstant(((Token)get(1)).text));
1054 String[] strings = new String[expCount+1];
1055 Expression[] expressions = new Expression[expCount];
1056 for(int i=0;i<expCount;++i) {
1057 strings[i] = ((Token)get(i*3+1)).text;
1058 expressions[i] = (Expression)get(i*3+2);
1060 strings[expCount] = ((Token)get(expCount*3+1)).text;
1061 return new EStringLiteral(strings, expressions);
1066 protected Object reduceOneCommand() {
1071 protected Object reduceManyCommands() {
1076 protected Object reduceStatementCommand() {
1077 // to be extended in subclasses
1082 protected Object reduceImportCommand() {
1083 // to be extended in subclasses
1088 protected Object reduceImportValueItem() {
1089 return new EVar(((Token)get(0)).text);
1093 protected Object reduceImportHiding() {
1094 EVar[] values = new EVar[(length()-2)/2];
1095 for(int i=0;i<values.length;++i)
1096 values[i] = (EVar)get(i*2+2);
1097 return new ImportDeclaration.ImportSpec(true, values);
1101 protected Object reduceImportShowing() {
1102 EVar[] values = new EVar[(length()-1)/2];
1103 for(int i=0;i<values.length;++i)
1104 values[i] = (EVar)get(i*2+1);
1105 return new ImportDeclaration.ImportSpec(false, values);
1109 protected Object reduceRuleDeclarations() {
1110 ArrayList<Object> declarations = new ArrayList<Object>(length()/2);
1111 for(int i=1;i<length();i+=2)
1112 declarations.add((Object)get(i));
1113 return declarations;
1116 private static final String[] EMPTY_STRING_ARRAY = new String[0];
1118 @SuppressWarnings("unchecked")
1120 protected Object reduceRuleDefinition() {
1121 String[] extendsNames = EMPTY_STRING_ARRAY;
1123 int extendsCount = (length() - 4) / 2;
1124 extendsNames = new String[extendsCount];
1125 for(int i=0;i<extendsCount;++i)
1126 extendsNames[i] = ((Token)get(3+i*2)).text;
1129 DRuleAst rule = new DRuleAst(
1130 ((Token)get(0)).id == SCLTerminals.ABSTRACT_RULE,
1131 ((Token)get(1)).text,
1134 ArrayList<Object> ruleDeclarations = (ArrayList<Object>)get(length()-1);
1135 ArrayList<Query> section = null;
1136 for(Object decl : ruleDeclarations) {
1137 if(decl instanceof DAnnotationAst) {
1138 DAnnotationAst annotation = (DAnnotationAst)decl;
1139 section = rule.getSection(annotation.id.text.substring(1));
1141 else if(decl instanceof Query) {
1143 section = rule.getSection("when");
1144 section.add((Query)decl);
1147 throw new InternalCompilerError();
1153 protected Object reduceQueryRuleDeclaration() {
1158 protected Object reduceMappingRelationDefinition() {
1159 TypeAst[] types = new TypeAst[length()-2];
1160 for(int i=0;i<types.length;++i)
1161 types[i] = (TypeAst)get(i+2);
1162 return new DMappingRelationAst(
1163 ((Token)get(1)).text,
1168 protected Object reduceTransformation() {
1169 return new ETransformation(
1170 ((Token)get(1)).text,
1171 new QConjunction((Query[])get(3))
1175 @SuppressWarnings("unchecked")
1177 protected Object reduceRelationDefinition() {
1178 return new DRelationAst((Expression)get(0),
1179 ((ArrayList<Object>)get(2)).toArray());
1183 protected Object reduceRecord() {
1184 FieldAssignment[] fields = new FieldAssignment[length()/2-1];
1185 for(int i=0;i<fields.length;++i)
1186 fields[i] = (FieldAssignment)get(2+i*2);
1187 return new ERecord(new EVar((Token)get(0)), fields);
1191 protected Object reduceField() {
1192 return new FieldAssignment(((Token)get(0)).text, (Expression)get(2));
1196 protected Object reduceFieldShorthand() {
1197 return new FieldAssignment(((Token)get(0)).text, null);
1201 protected Object reduceRecordConstructor() {
1203 for(idPos=0;idPos<length();idPos+=2)
1204 if(((Token)get(idPos)).id == SCLTerminals.ID)
1206 DAnnotationAst[] annotations = idPos == 0 ? DAnnotationAst.EMPTY_ARRAY : new DAnnotationAst[idPos/2];
1207 for(int i=0;i<idPos/2;++i)
1208 annotations[i] = new DAnnotationAst((Token)get(i*2),
1209 Arrays.asList((Expression)get(i*2+1)));
1210 TypeAst[] parameters = new TypeAst[(length()-idPos-1)/2];
1211 String[] fieldNames = new String[parameters.length];
1212 for(int i=0;i<parameters.length;++i) {
1213 FieldDescription fieldDesc = (FieldDescription)get(idPos+(i+1)*2);
1214 parameters[i] = fieldDesc.type;
1215 fieldNames[i] = fieldDesc.name;
1217 return new ConstructorAst(annotations, (Token)get(idPos), parameters, fieldNames);
1221 protected Object reduceFieldDescription() {
1222 return new FieldDescription(((Token)get(0)).text, (TypeAst)get(2));
1226 protected Object reduceEq() {
1227 return (Expression)get(2);
1231 protected Object reduceEquationBlock() {
1233 return new EEquations(Equation.EMPTY_ARRAY);
1234 Equation[] equations = new Equation[length()/2+1];
1235 for(int i=0;i<equations.length;++i)
1236 equations[i] = (Equation)get(2*i);
1237 return new EEquations(equations);
1241 protected Object reduceGuardEquation() {
1242 return new EqGuard((Expression)get(0));
1246 protected Object reduceBasicEquation() {
1247 return new EqBasic((Expression)get(0), (Expression)get(2));
1251 protected Object reduceViewPattern() {
1252 return new EViewPattern((Expression)get(1), (Expression)get(3));
1256 protected Object reduceConstraintStatement() {
1257 ConstructorAst constructor = (ConstructorAst)get(1);
1258 return new ConstraintStatement(constructor.name, constructor.parameters, constructor.fieldNames, constructor.annotations);
1263 protected Object reduceWhen() {
1265 new QConjunction((Query[])get(1)),
1266 (Expression)get(3));
1270 protected Object reduceDummy() {
1271 throw new UnsupportedOperationException();
1275 protected Object reduceRulesetDefinition() {
1276 Token name = (Token)get(1);
1277 EBlock block = (EBlock)get(3);
1278 return new DRulesetAst(name.text, block);
1282 protected Object reduceLocalInclude() {
1283 Token name = (Token)get(1);
1284 Expression value = (Expression)get(2);
1285 return new IncludeStatement(name, value);
1289 protected Object reduceConstraintSpec() {
1290 Expression[] expressions = new Expression[length()/2-1];
1291 for(int i=0;i<expressions.length;++i)
1292 expressions[i] = (Expression)get(2*i+1);
1297 protected Object reduceCHRSelect() {
1298 return new EPreCHRSelect((CHRAstQuery)get(3), (Expression)get(1));
1302 protected Object reduceCHRAtom() {
1303 return CHRAstAtom.atom((Expression)get(0));
1307 protected Object reduceCHREquals() {
1308 return new CHRAstEquals((Expression)get(0), (Expression)get(2));
1312 protected Object reduceCHRBinds() {
1313 return new CHRAstBinds((Expression)get(0), (Expression)get(2));
1317 protected Object reduceCHRConjunction() {
1318 CHRAstQuery[] conjuncts = new CHRAstQuery[(length()+1)/2];
1319 for(int i=0;i<conjuncts.length;++i)
1320 conjuncts[i] = (CHRAstQuery)get(i*2);
1321 return CHRAstConjunction.conjunction(conjuncts);
1325 protected Object reduceVerboseCHRConjunction() {
1326 CHRAstQuery[] conjuncts = new CHRAstQuery[(length()-1)/2];
1327 for(int i=0;i<conjuncts.length;++i)
1328 conjuncts[i] = (CHRAstQuery)get(i*2+1);
1329 return CHRAstConjunction.conjunction(conjuncts);
1333 protected Object reduceVerboseCHRStatement() {
1334 return new CHRStatement((CHRAstQuery)get(1), (CHRAstQuery)get(3));
1338 protected Object reduceCHRStatement() {
1339 return new CHRStatement((CHRAstQuery)get(0), (CHRAstQuery)get(2));