1 package org.simantics.scl.compiler.internal.parsing.parser;
4 import java.util.ArrayList;
5 import java.util.Arrays;
8 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
9 import org.simantics.scl.compiler.common.precedence.Associativity;
10 import org.simantics.scl.compiler.common.precedence.Precedence;
11 import org.simantics.scl.compiler.constants.CharacterConstant;
12 import org.simantics.scl.compiler.constants.StringConstant;
13 import org.simantics.scl.compiler.elaboration.equation.EqBasic;
14 import org.simantics.scl.compiler.elaboration.equation.EqGuard;
15 import org.simantics.scl.compiler.elaboration.equation.Equation;
16 import org.simantics.scl.compiler.elaboration.expressions.Case;
17 import org.simantics.scl.compiler.elaboration.expressions.EApply;
18 import org.simantics.scl.compiler.elaboration.expressions.EAsPattern;
19 import org.simantics.scl.compiler.elaboration.expressions.EBinary;
20 import org.simantics.scl.compiler.elaboration.expressions.EBinaryRightSide;
21 import org.simantics.scl.compiler.elaboration.expressions.EBlock;
22 import org.simantics.scl.compiler.elaboration.expressions.EConstant;
23 import org.simantics.scl.compiler.elaboration.expressions.EEnforce;
24 import org.simantics.scl.compiler.elaboration.expressions.EEquations;
25 import org.simantics.scl.compiler.elaboration.expressions.EFieldAccess;
26 import org.simantics.scl.compiler.elaboration.expressions.EIf;
27 import org.simantics.scl.compiler.elaboration.expressions.EIntegerLiteral;
28 import org.simantics.scl.compiler.elaboration.expressions.ELambda;
29 import org.simantics.scl.compiler.elaboration.expressions.EListComprehension;
30 import org.simantics.scl.compiler.elaboration.expressions.EListLiteral;
31 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
32 import org.simantics.scl.compiler.elaboration.expressions.EMatch;
33 import org.simantics.scl.compiler.elaboration.expressions.ERange;
34 import org.simantics.scl.compiler.elaboration.expressions.ERealLiteral;
35 import org.simantics.scl.compiler.elaboration.expressions.ERecord;
36 import org.simantics.scl.compiler.elaboration.expressions.ESelect;
37 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
38 import org.simantics.scl.compiler.elaboration.expressions.EStringLiteral;
39 import org.simantics.scl.compiler.elaboration.expressions.ETransformation;
40 import org.simantics.scl.compiler.elaboration.expressions.ETypeAnnotation;
41 import org.simantics.scl.compiler.elaboration.expressions.EVar;
42 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
43 import org.simantics.scl.compiler.elaboration.expressions.EViewPattern;
44 import org.simantics.scl.compiler.elaboration.expressions.Expression;
45 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpression;
46 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpressionGroup;
47 import org.simantics.scl.compiler.elaboration.expressions.Variable;
48 import org.simantics.scl.compiler.elaboration.expressions.accessor.ExpressionAccessor;
49 import org.simantics.scl.compiler.elaboration.expressions.accessor.FieldAccessor;
50 import org.simantics.scl.compiler.elaboration.expressions.accessor.IdAccessor;
51 import org.simantics.scl.compiler.elaboration.expressions.accessor.StringAccessor;
52 import org.simantics.scl.compiler.elaboration.expressions.block.BindStatement;
53 import org.simantics.scl.compiler.elaboration.expressions.block.CHRStatement;
54 import org.simantics.scl.compiler.elaboration.expressions.block.ConstraintStatement;
55 import org.simantics.scl.compiler.elaboration.expressions.block.GuardStatement;
56 import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement;
57 import org.simantics.scl.compiler.elaboration.expressions.block.RuleStatement;
58 import org.simantics.scl.compiler.elaboration.expressions.block.Statement;
59 import org.simantics.scl.compiler.elaboration.expressions.list.ListAssignment;
60 import org.simantics.scl.compiler.elaboration.expressions.list.ListGenerator;
61 import org.simantics.scl.compiler.elaboration.expressions.list.ListGuard;
62 import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifier;
63 import org.simantics.scl.compiler.elaboration.expressions.list.ListSeq;
64 import org.simantics.scl.compiler.elaboration.expressions.list.ListThen;
65 import org.simantics.scl.compiler.elaboration.expressions.records.FieldAssignment;
66 import org.simantics.scl.compiler.elaboration.java.Builtins;
67 import org.simantics.scl.compiler.elaboration.query.QAlternative;
68 import org.simantics.scl.compiler.elaboration.query.QConjunction;
69 import org.simantics.scl.compiler.elaboration.query.QDisjunction;
70 import org.simantics.scl.compiler.elaboration.query.QNegation;
71 import org.simantics.scl.compiler.elaboration.query.Query;
72 import org.simantics.scl.compiler.elaboration.query.pre.QPreBinds;
73 import org.simantics.scl.compiler.elaboration.query.pre.QPreEquals;
74 import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard;
75 import org.simantics.scl.compiler.errors.Locations;
76 import org.simantics.scl.compiler.internal.parsing.Symbol;
77 import org.simantics.scl.compiler.internal.parsing.Token;
78 import org.simantics.scl.compiler.internal.parsing.declarations.ConstructorAst;
79 import org.simantics.scl.compiler.internal.parsing.declarations.DAnnotationAst;
80 import org.simantics.scl.compiler.internal.parsing.declarations.DClassAst;
81 import org.simantics.scl.compiler.internal.parsing.declarations.DDataAst;
82 import org.simantics.scl.compiler.internal.parsing.declarations.DDerivingInstanceAst;
83 import org.simantics.scl.compiler.internal.parsing.declarations.DDocumentationAst;
84 import org.simantics.scl.compiler.internal.parsing.declarations.DEffectAst;
85 import org.simantics.scl.compiler.internal.parsing.declarations.DFixityAst;
86 import org.simantics.scl.compiler.internal.parsing.declarations.DImportJavaAst;
87 import org.simantics.scl.compiler.internal.parsing.declarations.DInstanceAst;
88 import org.simantics.scl.compiler.internal.parsing.declarations.DMappingRelationAst;
89 import org.simantics.scl.compiler.internal.parsing.declarations.DModuleHeader;
90 import org.simantics.scl.compiler.internal.parsing.declarations.DRelationAst;
91 import org.simantics.scl.compiler.internal.parsing.declarations.DRuleAst;
92 import org.simantics.scl.compiler.internal.parsing.declarations.DTypeAst;
93 import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst;
94 import org.simantics.scl.compiler.internal.parsing.declarations.DValueTypeAst;
95 import org.simantics.scl.compiler.internal.parsing.declarations.DeclarationAst;
96 import org.simantics.scl.compiler.internal.parsing.declarations.FieldDescription;
97 import org.simantics.scl.compiler.internal.parsing.declarations.FundepAst;
98 import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
99 import org.simantics.scl.compiler.internal.parsing.types.TApplyAst;
100 import org.simantics.scl.compiler.internal.parsing.types.TEffectAst;
101 import org.simantics.scl.compiler.internal.parsing.types.TForAllAst;
102 import org.simantics.scl.compiler.internal.parsing.types.TFunctionAst;
103 import org.simantics.scl.compiler.internal.parsing.types.TListAst;
104 import org.simantics.scl.compiler.internal.parsing.types.TPredAst;
105 import org.simantics.scl.compiler.internal.parsing.types.TTupleAst;
106 import org.simantics.scl.compiler.internal.parsing.types.TVarAst;
107 import org.simantics.scl.compiler.internal.parsing.types.TypeAst;
108 import org.simantics.scl.compiler.module.ImportDeclaration;
109 import org.simantics.scl.compiler.types.Types;
112 public class SCLParserImpl extends SCLParser {
114 private final SCLPostLexer lexer;
115 private SCLParserOptions options;
117 public SCLParserImpl(Reader reader) {
118 lexer = new SCLPostLexer(reader);
121 public void setParserOptions(SCLParserOptions options) {
122 this.options = options;
123 lexer.setParserOptions(options);
126 public boolean isEmpty() throws Exception {
127 return lexer.peekToken().id == SCLTerminals.EOF;
131 protected Token nextToken() {
133 Token token = lexer.nextToken();
134 /*System.out.println("TOKEN " + token.text + " (" + TERMINAL_NAMES[token.id] + ")" +
136 + Locations.beginOf(token.location) + ".."
137 + Locations.endOf(token.location) + "]");*/
139 } catch(Exception e) {
140 if(e instanceof RuntimeException)
141 throw (RuntimeException)e;
143 throw new RuntimeException(e);
148 protected Object reduceDeclarations() {
149 ArrayList<DeclarationAst> declarations = new ArrayList<DeclarationAst>(length()/2);
150 for(int i=1;i<length();i+=2)
151 declarations.add((DeclarationAst)get(i));
156 protected Object reduceModule() {
157 ArrayList<DeclarationAst> declarations = new ArrayList<DeclarationAst>(length()/2+1);
158 for(int i=0;i<length();i+=2) {
159 DeclarationAst declaration = (DeclarationAst)get(i);
160 if(declaration == null)
161 throw new NullPointerException();
162 declarations.add(declaration);
168 protected Object reduceModuleHeader() {
169 FieldAssignment[] fields = new FieldAssignment[length()/2-1];
170 for(int i=0;i<fields.length;++i)
171 fields[i] = (FieldAssignment)get(2+i*2);
172 return new DModuleHeader(fields);
176 protected Object reduceLocalTypeAnnotation() {
179 return new ETypeAnnotation((Expression)get(0), (TypeAst)get(2));
183 protected Object reduceTypeAnnotation() {
184 EVar[] names = new EVar[length()/2];
185 for(int i=0;i<names.length;++i)
186 names[i] = (EVar)get(i*2);
187 return new DValueTypeAst(
189 (TypeAst)get(length()-1)
194 protected Object reduceValueDefinition() {
195 Expression rhs = (Expression)get(1);
196 return new DValueAst((Expression)get(0), rhs);
200 protected Object reduceDataDefinition() {
202 ArrayList<String> parameters = new ArrayList<String>();
203 while(i < length()) {
204 Token token = (Token)get(i++);
205 if(token.id != SCLTerminals.ID)
207 parameters.add(token.text);
209 ArrayList<ConstructorAst> constructors = new ArrayList<ConstructorAst>();
210 for(;i < length();i+=2)
211 constructors.add((ConstructorAst)get(i));
213 ((Token)get(1)).text,
214 parameters.toArray(new String[parameters.size()]),
215 constructors.toArray(new ConstructorAst[constructors.size()]),
221 protected Object reduceTypeDefinition() {
223 ArrayList<String> parameters = new ArrayList<String>();
225 Token token = (Token)get(i++);
226 if(token.id != SCLTerminals.ID)
228 parameters.add(token.text);
231 ((Token)get(1)).text,
232 parameters.toArray(new String[parameters.size()]),
237 @SuppressWarnings("unchecked")
239 protected Object reduceClassDefinition() {
241 ArrayList<TypeAst> context;
242 if(get(i) instanceof Token)
243 context = new ArrayList<TypeAst>(0);
245 context = (ArrayList<TypeAst>)get(i++);
246 String name = ((Token)get(i++)).text;
247 ArrayList<String> parameters = new ArrayList<String>();
248 while(i < length()) {
249 Token token = (Token)get(i);
250 if(token.id != SCLTerminals.ID)
252 parameters.add(token.text);
255 ArrayList<DeclarationAst> declarations = null;
256 FundepAst[] fundeps = FundepAst.EMPTY_ARRAY;
257 while(i < length()) {
258 Token token = (Token)get(i++);
259 if(token.id == SCLTerminals.WHERE) {
260 declarations = (ArrayList<DeclarationAst>)get(i++);
262 else if(token.id == SCLTerminals.BAR) {
263 fundeps = (FundepAst[])get(i++);
266 throw new InternalCompilerError();
268 return new DClassAst(context, name,
269 parameters.toArray(new String[parameters.size()]),
275 protected Object reduceFundep() {
276 String[] from = new String[length()-2];
277 for(int i=0;i<from.length;++i)
278 from[i] = ((Token)get(i)).text;
279 String to = ((Token)get(length()-1)).text;
280 return new FundepAst(from, to);
284 protected Object reduceFundeps() {
285 FundepAst[] fundeps = new FundepAst[(length()+1)/2];
286 for(int i=0;i<fundeps.length;++i)
287 fundeps[i] = (FundepAst)get(i*2);
291 @SuppressWarnings("unchecked")
293 protected Object reduceInstanceDefinition() {
295 ArrayList<TypeAst> context;
296 if(get(i) instanceof Token)
297 context = new ArrayList<TypeAst>(0);
299 context = (ArrayList<TypeAst>)get(i++);
300 Token nameToken = (Token)get(i++);
301 EVar name = new EVar(nameToken.location, nameToken.text);
302 ArrayList<TypeAst> parameters = new ArrayList<TypeAst>();
303 while(i < length()) {
304 Object symbol = get(i++);
305 if(symbol instanceof Token)
307 parameters.add((TypeAst)symbol);
309 ArrayList<DeclarationAst> declarations = null;
311 declarations = (ArrayList<DeclarationAst>)get(i);
312 return new DInstanceAst(context, name,
313 parameters.toArray(new TypeAst[parameters.size()]),
317 @SuppressWarnings("unchecked")
319 protected Object reduceDerivingInstanceDefinition() {
321 ArrayList<TypeAst> context;
322 if(get(i) instanceof Token)
323 context = new ArrayList<TypeAst>(0);
325 context = (ArrayList<TypeAst>)get(i++);
326 Token nameToken = (Token)get(i++);
327 EVar name = new EVar(nameToken.location, nameToken.text);
328 ArrayList<TypeAst> parameters = new ArrayList<TypeAst>();
329 while(i < length()) {
330 Object symbol = get(i++);
331 parameters.add((TypeAst)symbol);
333 return new DDerivingInstanceAst(context, name,
334 parameters.toArray(new TypeAst[parameters.size()]));
338 protected Object reduceDocumentationString() {
339 return new DDocumentationAst(((Token)get(1)).text);
343 protected Object reduceAnnotation() {
344 ArrayList<Expression> parameters = new ArrayList<Expression>(length()-1);
345 for(int i=1;i<length();++i)
346 parameters.add((Expression)get(i));
347 return new DAnnotationAst((Token)get(0), parameters);
351 protected Object reducePrecedenceDefinition() {
352 EVar[] symbols = new EVar[length()/2];
353 for(int i=0;i<symbols.length;++i)
354 symbols[i] = (EVar)get(2*i + 2);
355 Associativity associativity;
356 Token token = (Token)get(0);
357 if(token.text.equals("infixl"))
358 associativity = Associativity.LEFT;
359 else if(token.text.equals("infixr"))
360 associativity = Associativity.RIGHT;
362 associativity = Associativity.NONASSOC;
363 return new DFixityAst(
365 Integer.parseInt(((Token)get(1)).text),
371 protected Object reduceImport() {
372 // (AS ID)? importSpec?
374 String importKeyword = ((Token)get(pos++)).text; // (IMPORT | INCLUDE)
375 ++pos; // BEGIN_STRING
376 String moduleName = ((Token)get(pos++)).text; // END_STRING
377 String localName = "";
379 Object temp = get(pos);
380 if(temp instanceof Token) {
381 Token token = (Token)temp;
382 if(token.id == SCLTerminals.AS) {
384 localName = ((Token)get(pos++)).text; // ID
388 ImportDeclaration.ImportSpec spec = ImportDeclaration.DEFAULT_SPEC;
390 spec = (ImportDeclaration.ImportSpec)get(pos++);
391 return new ImportDeclaration(moduleName, localName,
392 importKeyword.equals("include"),
397 protected Object reduceJustImport() {
401 @SuppressWarnings("unchecked")
403 protected Object reduceImportJava() {
404 return new DImportJavaAst(((Token)get(2)).text, (ArrayList<DeclarationAst>)get(4));
408 protected Object reduceEffectDefinition() {
409 return new DEffectAst(
410 ((Token)get(1)).text,
411 ((Token)get(3)).text,
412 ((Token)get(5)).text);
416 protected Object reduceVarId() {
417 return new EVar(((Token)get(0)).text);
421 protected Object reduceEscapedSymbol() {
422 return new EVar(((Token)get(0)).text);
426 protected Object reduceTupleTypeConstructor() {
427 return new TVarAst(Types.tupleConstructor(length()-1).name);
431 protected Object reduceArrow() {
433 TypeAst result = (TypeAst)get(i);
436 if( ((Token)get(i+1)).text.equals("=>") )
437 result = new TPredAst((TypeAst)get(i), result);
439 result = new TFunctionAst((TypeAst)get(i), result);
446 protected Object reduceBinary() {
450 EVar negation = null;
451 if(get(i) instanceof Token) {
452 Token token = (Token)get(i++);
453 negation = new EVar(token.location, token.text);
455 EBinary binary = new EBinary((Expression)get(i++), negation);
456 while(i < length()) {
457 EVar operator = (EVar)get(i++);
458 Expression right = (Expression)get(i++);
459 binary.rights.add(new EBinaryRightSide(operator, right));
465 protected Object reduceSimpleRhs() {
469 EBlock block = (EBlock)get(3);
470 Expression expression = (Expression)get(1);
471 block.addStatement(new GuardStatement(expression));
472 block.location = Locations.location(Locations.beginOf(expression.location), Locations.endOf(block.location));
477 private GuardedExpressionGroup reduceGuardedExpressionGroup(int length) {
478 GuardedExpression[] expressions = new GuardedExpression[length];
479 for(int i=0;i<expressions.length;++i) {
480 expressions[i] = (GuardedExpression)get(i);
482 return new GuardedExpressionGroup(expressions);
486 protected Object reduceGuardedRhs() {
487 int length = length();
488 if(length > 2 && get(length-2) instanceof Token) {
489 EBlock block = (EBlock)get(length-1);
490 block.addStatement(new GuardStatement(reduceGuardedExpressionGroup(length-2)));
491 block.location = Locations.NO_LOCATION;
495 return reduceGuardedExpressionGroup(length);
499 protected Object reduceStatements() {
500 EBlock block = new EBlock();
502 for(int i=1;i<length();i+=2)
503 block.addStatement((Statement)get(i));
508 protected Object reduceConstructor() {
510 for(idPos=0;idPos<length();idPos+=2)
511 if(((Token)get(idPos)).id == SCLTerminals.ID)
513 DAnnotationAst[] annotations = idPos == 0 ? DAnnotationAst.EMPTY_ARRAY : new DAnnotationAst[idPos/2];
514 for(int i=0;i<idPos/2;++i)
515 annotations[i] = new DAnnotationAst((Token)get(i*2),
516 Arrays.asList((Expression)get(i*2+1)));
517 TypeAst[] parameters = new TypeAst[length()-idPos-1];
518 for(int i=0;i<parameters.length;++i)
519 parameters[i] = (TypeAst)get(i+idPos+1);
520 return new ConstructorAst(annotations, ((Token)get(idPos)).text, parameters, null);
524 protected Object reduceContext() {
525 ArrayList<TypeAst> result = new ArrayList<TypeAst>(length()/2-1);
526 for(int i=1;i<length()-2;i+=2)
527 result.add((TypeAst)get(i));
532 protected Object reduceTypeVar() {
533 return new TVarAst(((Token)get(0)).text);
537 protected Object reduceTupleType() {
539 return new TTupleAst(TypeAst.EMPTY_ARRAY);
541 Symbol sym = (Symbol)get(1);
542 sym.location = Locations.NO_LOCATION;
545 int dim = length()/2;
546 TypeAst[] parameters = new TypeAst[dim];
547 for(int i=0;i<dim;++i)
548 parameters[i] = (TypeAst)get(i*2+1);
549 return new TTupleAst(parameters);
553 protected Object reduceListType() {
554 return new TListAst((TypeAst)get(1));
558 protected Object reduceListTypeConstructor() {
559 return new TVarAst("[]");
563 protected Object reduceTupleConstructor() {
564 return new EVar(Types.tupleConstructor(length()-1).name);
568 protected Object reduceVar() {
573 protected Object reduceBlank() {
574 return new EVar("_");
578 protected Object reduceInteger() {
579 return new EIntegerLiteral(((Token)get(0)).text);
583 protected Object reduceFloat() {
584 return new ERealLiteral(((Token)get(0)).text);
588 protected Object reduceString() {
593 protected Object reduceChar() {
594 String text = ((Token)get(0)).text;
595 char c = text.charAt(text.length()-2);
596 if(text.length() == 4) {
598 case 'n': c = '\n'; break;
599 case 't': c = '\t'; break;
600 case 'b': c = '\b'; break;
601 case 'f': c = '\f'; break;
602 case 'r': c = '\r'; break;
605 return new ELiteral(new CharacterConstant(c));
609 protected Object reduceTuple() {
611 return new EConstant(Builtins.TUPLE_CONSTRUCTORS[0]);
613 Symbol sym = (Symbol)get(1);
614 sym.location = Locations.NO_LOCATION;
617 int dim = length()/2;
618 Expression[] parameters = new Expression[dim];
619 for(int i=0;i<dim;++i)
620 parameters[i] = (Expression)get(i*2+1);
621 EConstant tupleConstructor = new EConstant(Builtins.TUPLE_CONSTRUCTORS[dim]);
622 tupleConstructor.location = Locations.location(
623 Locations.beginOf(((Token)get(0)).location),
624 Locations.endOf(((Token)get(length()-1)).location));
625 return new EApply(tupleConstructor, parameters);
628 public static Expression rightSection(EVar op, Expression e) {
629 long loc = Locations.combine(op.location, e.location);
630 Variable var = new Variable("rightSectionTemp");
631 return new ESimpleLambda(loc, var,
632 new EApply(loc, op, new EVariable(loc, var), e));
636 protected Object reduceRightSection() {
637 Variable var = new Variable("rightSectionTemp");
638 long loc = Locations.combine(((Token)get(0)).location, ((Token)get(length()-1)).location);
639 EVar symbol = (EVar)get(1);
640 return new ESimpleLambda(var,
641 new EApply(loc, symbol,
642 new EVariable(loc, var), (Expression)get(2)));
646 protected Object reduceLeftSection() {
647 return new EApply((EVar)get(2), (Expression)get(1));
651 protected Object reduceListLiteral() {
653 return new EListLiteral(Expression.EMPTY_ARRAY);
654 int dim = length()/2;
655 Expression[] components = new Expression[dim];
656 for(int i=0;i<dim;++i)
657 components[i] = (Expression)get(i*2+1);
658 return new EListLiteral(components);
662 protected Object reduceRange() {
670 protected Object reduceListComprehension() {
671 ListQualifier qualifier = (ListQualifier)get(3);
672 for(int i=5;i<length();i+=2) {
673 ListQualifier right = (ListQualifier)get(i);
674 if(right instanceof ListThen) {
675 ((ListThen) right).setLeft(qualifier);
679 qualifier = new ListSeq(qualifier, right);
681 return new EListComprehension((Expression)get(1), qualifier);
685 protected Object reduceAs() {
686 Token id = (Token)get(0);
687 return new EAsPattern(new EVar(id.location, id.text), (Expression)get(2));
691 protected Object reduceGuardedExpEq() {
692 Expression[] guards = new Expression[length()/2-1];
693 for(int i=0;i<guards.length;++i)
694 guards[i] = (Expression)get(i*2+1);
695 return new GuardedExpression(guards, (Expression)get(length()-1));
699 protected Object reduceLambda() {
700 Expression[] patterns = new Expression[length()-3];
701 for(int i=0;i<patterns.length;++i)
702 patterns[i] = (Expression)get(i+1);
703 Case case_ = new Case(patterns, (Expression)get(length()-1));
704 case_.setLhs(Locations.combine(patterns[0].location, patterns[patterns.length-1].location));
705 return new ELambda(case_);
709 protected Object reduceLambdaMatch() {
710 Case[] cases = new Case[length()/2-1];
711 for(int i=0;i<cases.length;++i)
712 cases[i] = (Case)get(i*2+2);
713 return new ELambda(cases);
717 protected Object reduceLet() {
718 EBlock block = (EBlock)get(1);
719 Expression expression = (Expression)get(3);
720 block.addStatement(new GuardStatement(expression));
721 Token letToken = (Token)get(0);
722 block.location = Locations.location(
723 Locations.beginOf(letToken.location),
724 Locations.endOf(expression.location));
729 protected Object reduceIf() {
733 length() == 6 ? (Expression)get(5) : null);
737 protected Object reduceMatch() {
738 Case[] cases = new Case[length()/2-2];
739 for(int i=0;i<cases.length;++i)
740 cases[i] = (Case)get(i*2+4);
741 return new EMatch((Expression)get(1), cases);
745 protected Object reduceDo() {
746 EBlock block = (EBlock)get(1);
747 Token doToken = (Token)get(0);
748 block.setMonadic( doToken.text.equals("mdo") );
749 block.location = Locations.location(Locations.beginOf(doToken.location), Locations.endOf(block.location));
754 protected Object reduceSelect() {
755 return new ESelect(((Token)get(0)).id, (Expression)get(1), new QConjunction((Query[])get(3)));
759 protected Object reduceEnforce() {
760 return new EEnforce(new QConjunction((Query[])get(1)));
764 protected Object reduceApply() {
767 Expression[] parameters = new Expression[length()-1];
768 for(int i=0;i<parameters.length;++i)
769 parameters[i] = (Expression)get(i+1);
770 return new EApply((Expression)get(0), parameters);
774 protected Object reduceSymbol() {
775 return new EVar(((Token)get(0)).text);
779 protected Object reduceEscapedId() {
780 return new EVar(((Token)get(0)).text);
784 protected Object reduceMinus() {
785 return new EVar(((Token)get(0)).text);
789 protected Object reduceLess() {
790 return new EVar(((Token)get(0)).text);
794 protected Object reduceGreater() {
795 return new EVar(((Token)get(0)).text);
799 protected Object reduceDot() {
800 return new EVar(((Token)get(0)).text);
804 protected Object reduceCase() {
805 return new Case((Expression)get(0), (Expression)get(1));
809 protected Object reduceGuardQualifier() {
810 return new ListGuard((Expression)get(0));
814 protected Object reduceLetQualifier() {
815 return new ListAssignment((Expression)get(0), (Expression)get(2));
819 protected Object reduceBindQualifier() {
820 return new ListGenerator((Expression)get(0), (Expression)get(2));
824 protected Object reduceThenQualifier() {
825 return new ListThen((Expression)get(1), length()==4 ? (Expression)get(3) : null);
829 protected Object reduceGuardStatement() {
830 return new GuardStatement((Expression)get(0));
834 protected Object reduceLetStatement() {
835 return new LetStatement((Expression)get(0), (Expression)get(1));
839 protected Object reduceBindStatement() {
840 return new BindStatement((Expression)get(0), (Expression)get(2));
844 protected Object reduceSimpleCaseRhs() {
849 protected Object reduceGuardedCaseRhs() {
850 GuardedExpression[] expressions = new GuardedExpression[length()];
851 for(int i=0;i<expressions.length;++i)
852 expressions[i] = (GuardedExpression)get(i);
853 return new GuardedExpressionGroup(expressions);
857 protected Object reduceGuardedExpArrow() {
858 Expression[] guards = new Expression[length()/2-1];
859 for(int i=0;i<guards.length;++i)
860 guards[i] = (Expression)get(i*2+1);
861 return new GuardedExpression(guards, (Expression)get(length()-1));
865 protected Object reduceEffect() {
866 ArrayList<TypeAst> effects = new ArrayList<TypeAst>(length()/2-1);
867 for(int i=1;i<length()-1;i+=2) {
868 Token token = (Token)get(i);
869 TVarAst ast = new TVarAst(token.text);
870 ast.location = token.location;
873 return new TEffectAst(effects, (TypeAst)get(length()-1));
877 protected Object reduceJustEtype() {
882 protected Object reduceForAll() {
883 String[] vars = new String[length()-3];
884 for(int i=0;i<vars.length;++i)
885 vars[i] = ((Token)get(i+1)).text;
886 return new TForAllAst(vars, (TypeAst)get(length()-1));
890 protected Object reduceApplyType() {
891 TypeAst[] parameters = new TypeAst[length()-1];
892 for(int i=0;i<parameters.length;++i)
893 parameters[i] = (TypeAst)get(i+1);
894 return new TApplyAst((TypeAst)get(0), parameters);
897 @SuppressWarnings("unchecked")
899 protected void postReduce(Object reduced) {
900 if(!(reduced instanceof Symbol))
902 Symbol sym = (Symbol)reduced;
903 if(sym.location != Locations.NO_LOCATION || length() == 0)
905 Object first = get(0);
906 if(!(first instanceof Symbol)) {
907 if(first instanceof List) {
908 List<Object> ll = (List<Object>)first;
912 Object[] ll = (Object[])first;
919 Object last = get(length()-1);
920 if(!(last instanceof Symbol)) {
921 if(last instanceof List) {
922 List<Object> ll = (List<Object>)last;
923 last = ll.get(ll.size()-1);
926 Object[] ll = (Object[])last;
928 last = ll[ll.length-1];
930 last = get(length()-2);
933 sym.location = (((Symbol)first).location & 0xffffffff00000000L)
934 | (((Symbol)last).location & 0xffffffffL);
935 /*for(int i=0;i<length();++i) {
937 System.out.print(obj.getClass().getSimpleName());
938 if(obj instanceof Token) {
939 Token t = (Token)obj;
940 System.out.print("(" + t.text + ")");
942 if(obj instanceof Symbol) {
943 Symbol s = (Symbol)obj;
944 System.out.print("["+ Locations.beginOf(s.location) + "-" + Locations.endOf(s.location) + "]");
946 System.out.print(" ");
948 System.out.println("-> " + reduced.getClass().getSimpleName() + " " +
949 Locations.beginOf(sym.location) + "-" + Locations.endOf(sym.location));*/
953 protected RuntimeException syntaxError(Token token, String description) {
954 throw new SCLSyntaxErrorException(token.location, description);
958 protected Object reduceIdAccessor() {
959 return new IdAccessor('.', ((Token)get(0)).text);
963 protected Object reduceStringAccessor() {
964 return new StringAccessor('.', ((Token)get(1)).text);
968 protected Object reduceExpAccessor() {
969 return new ExpressionAccessor('.', (Expression)get(1));
973 protected Object reduceFieldAccess() {
976 Expression result = (Expression)get(0);
977 for(int i=2;i<length();i+=2) {
978 FieldAccessor accessor = (FieldAccessor)get(i);
979 accessor.accessSeparator = ((Token)get(i-1)).text.charAt(0);
980 result = new EFieldAccess(result, accessor);
986 protected Object reduceQueryBlock() {
988 return Query.EMPTY_ARRAY;
989 Query[] queries = new Query[length()/2];
990 for(int i=0;i<queries.length;++i)
991 queries[i] = (Query)get(2*i+1);
996 protected Object reduceGuardQuery() {
997 return new QPreGuard((Expression)get(0));
1001 protected Object reduceEqualsQuery() {
1002 return new QPreEquals((Expression)get(0), (Expression)get(2));
1006 protected Object reduceBindQuery() {
1007 return new QPreBinds((Expression)get(0), (Expression)get(2));
1011 protected Object reduceCompositeQuery() {
1012 Query[] queries = (Query[])get(1);
1013 switch(((Token)get(0)).text.charAt(1)) {
1014 case '&': return new QConjunction(queries);
1015 case '|': return new QDisjunction(queries);
1016 case '!': return new QNegation(new QConjunction(queries));
1017 case '?': return new QAlternative(queries);
1018 default: throw new InternalCompilerError();
1023 protected Object reduceRuleStatement() {
1024 return new RuleStatement((Expression)get(0), new QConjunction((Query[])get(2)));
1028 protected Object reduceHashedId() {
1029 return new EVar("#" + ((Token)get(1)).text);
1033 protected Object reduceStringLiteral() {
1034 int expCount = length()/3;
1036 return new ELiteral(new StringConstant(((Token)get(1)).text));
1038 String[] strings = new String[expCount+1];
1039 Expression[] expressions = new Expression[expCount];
1040 for(int i=0;i<expCount;++i) {
1041 strings[i] = ((Token)get(i*3+1)).text;
1042 expressions[i] = (Expression)get(i*3+2);
1044 strings[expCount] = ((Token)get(expCount*3+1)).text;
1045 return new EStringLiteral(strings, expressions);
1050 protected Object reduceOneCommand() {
1055 protected Object reduceManyCommands() {
1060 protected Object reduceStatementCommand() {
1061 // to be extended in subclasses
1066 protected Object reduceImportCommand() {
1067 // to be extended in subclasses
1072 protected Object reduceImportValueItem() {
1073 return new EVar(((Token)get(0)).text);
1077 protected Object reduceImportHiding() {
1078 EVar[] values = new EVar[(length()-2)/2];
1079 for(int i=0;i<values.length;++i)
1080 values[i] = (EVar)get(i*2+2);
1081 return new ImportDeclaration.ImportSpec(true, values);
1085 protected Object reduceImportShowing() {
1086 EVar[] values = new EVar[(length()-1)/2];
1087 for(int i=0;i<values.length;++i)
1088 values[i] = (EVar)get(i*2+1);
1089 return new ImportDeclaration.ImportSpec(false, values);
1093 protected Object reduceRuleDeclarations() {
1094 ArrayList<Object> declarations = new ArrayList<Object>(length()/2);
1095 for(int i=1;i<length();i+=2)
1096 declarations.add((Object)get(i));
1097 return declarations;
1100 private static final String[] EMPTY_STRING_ARRAY = new String[0];
1102 @SuppressWarnings("unchecked")
1104 protected Object reduceRuleDefinition() {
1105 String[] extendsNames = EMPTY_STRING_ARRAY;
1107 int extendsCount = (length() - 4) / 2;
1108 extendsNames = new String[extendsCount];
1109 for(int i=0;i<extendsCount;++i)
1110 extendsNames[i] = ((Token)get(3+i*2)).text;
1113 DRuleAst rule = new DRuleAst(
1114 ((Token)get(0)).id == SCLTerminals.ABSTRACT_RULE,
1115 ((Token)get(1)).text,
1118 ArrayList<Object> ruleDeclarations = (ArrayList<Object>)get(length()-1);
1119 ArrayList<Query> section = null;
1120 for(Object decl : ruleDeclarations) {
1121 if(decl instanceof DAnnotationAst) {
1122 DAnnotationAst annotation = (DAnnotationAst)decl;
1123 section = rule.getSection(annotation.id.text.substring(1));
1125 else if(decl instanceof Query) {
1127 section = rule.getSection("when");
1128 section.add((Query)decl);
1131 throw new InternalCompilerError();
1137 protected Object reduceQueryRuleDeclaration() {
1142 protected Object reduceMappingRelationDefinition() {
1143 TypeAst[] types = new TypeAst[length()-2];
1144 for(int i=0;i<types.length;++i)
1145 types[i] = (TypeAst)get(i+2);
1146 return new DMappingRelationAst(
1147 ((Token)get(1)).text,
1152 protected Object reduceTransformation() {
1153 return new ETransformation(
1154 ((Token)get(1)).text,
1155 new QConjunction((Query[])get(3))
1159 @SuppressWarnings("unchecked")
1161 protected Object reduceRelationDefinition() {
1162 return new DRelationAst((Expression)get(0),
1163 ((ArrayList<Object>)get(2)).toArray());
1167 protected Object reduceRecord() {
1168 FieldAssignment[] fields = new FieldAssignment[length()/2-1];
1169 for(int i=0;i<fields.length;++i)
1170 fields[i] = (FieldAssignment)get(2+i*2);
1171 return new ERecord((Token)get(0), fields);
1175 protected Object reduceField() {
1176 return new FieldAssignment(((Token)get(0)).text, (Expression)get(2));
1180 protected Object reduceFieldShorthand() {
1181 return new FieldAssignment(((Token)get(0)).text, null);
1185 protected Object reduceRecordConstructor() {
1187 for(idPos=0;idPos<length();idPos+=2)
1188 if(((Token)get(idPos)).id == SCLTerminals.ID)
1190 DAnnotationAst[] annotations = idPos == 0 ? DAnnotationAst.EMPTY_ARRAY : new DAnnotationAst[idPos/2];
1191 for(int i=0;i<idPos/2;++i)
1192 annotations[i] = new DAnnotationAst((Token)get(i*2),
1193 Arrays.asList((Expression)get(i*2+1)));
1194 TypeAst[] parameters = new TypeAst[(length()-idPos-1)/2];
1195 String[] fieldNames = new String[parameters.length];
1196 for(int i=0;i<parameters.length;++i) {
1197 FieldDescription fieldDesc = (FieldDescription)get(idPos+(i+1)*2);
1198 parameters[i] = fieldDesc.type;
1199 fieldNames[i] = fieldDesc.name;
1201 return new ConstructorAst(annotations, ((Token)get(idPos)).text, parameters, fieldNames);
1205 protected Object reduceFieldDescription() {
1206 return new FieldDescription(((Token)get(0)).text, (TypeAst)get(2));
1210 protected Object reduceEq() {
1211 return (Expression)get(2);
1215 protected Object reduceEquationBlock() {
1217 return new EEquations(Equation.EMPTY_ARRAY);
1218 Equation[] equations = new Equation[length()/2+1];
1219 for(int i=0;i<equations.length;++i)
1220 equations[i] = (Equation)get(2*i);
1221 return new EEquations(equations);
1225 protected Object reduceGuardEquation() {
1226 return new EqGuard((Expression)get(0));
1230 protected Object reduceBasicEquation() {
1231 return new EqBasic((Expression)get(0), (Expression)get(2));
1235 protected Object reduceViewPattern() {
1236 return new EViewPattern((Expression)get(1), (Expression)get(3));
1240 protected Object reduceCHRStatement() {
1241 return new CHRStatement((ListQualifier[])get(0), (ListQualifier[])get(2));
1245 protected Object reduceConstraintStatement() {
1246 TypeAst[] parameterTypes = new TypeAst[length()-2];
1247 for(int i=0;i<parameterTypes.length;++i)
1248 parameterTypes[i] = (TypeAst)get(2+i);
1249 return new ConstraintStatement((Token)get(1), parameterTypes);
1253 protected Object reduceCHRQuery() {
1254 ListQualifier[] query = new ListQualifier[(length()+1)/2];
1255 for(int i=0;i<query.length;++i)
1256 query[i] = (ListQualifier)get(i*2);
1262 protected Object reduceWhen() {
1264 new QConjunction((Query[])get(1)),
1265 (Expression)get(3));
1269 protected Object reduceVerboseCHRQuery() {
1270 ListQualifier[] query = new ListQualifier[(length()-1)/2];
1271 for(int i=0;i<query.length;++i)
1272 query[i] = (ListQualifier)get(i*2+1);
1277 protected Object reduceVerboseCHRStatement() {
1278 return new CHRStatement((ListQualifier[])get(1), (ListQualifier[])get(3));
1282 protected Object reduceDummy() {
1283 throw new UnsupportedOperationException();