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.TPredAst;
115 import org.simantics.scl.compiler.internal.parsing.types.TTupleAst;
116 import org.simantics.scl.compiler.internal.parsing.types.TVarAst;
117 import org.simantics.scl.compiler.internal.parsing.types.TypeAst;
118 import org.simantics.scl.compiler.module.ImportDeclaration;
119 import org.simantics.scl.compiler.types.Types;
122 public class SCLParserImpl extends SCLParser {
124 private final SCLPostLexer lexer;
125 private SCLParserOptions options;
126 private CompilationContext context;
128 public SCLParserImpl(Reader reader) {
129 this.lexer = new SCLPostLexer(reader);
132 public SCLPostLexer getLexer() {
136 public void setCompilationContext(CompilationContext context) {
137 this.context = context;
138 lexer.setCompilationContext(context);
141 public void setParserOptions(SCLParserOptions options) {
142 this.options = options;
143 lexer.setParserOptions(options);
146 public boolean isEmpty() throws Exception {
147 return lexer.peekToken().id == SCLTerminals.EOF;
151 protected Token nextToken() {
153 Token token = lexer.nextToken();
154 /*System.out.println("TOKEN " + token.text + " (" + TERMINAL_NAMES[token.id] + ")" +
156 + Locations.beginOf(token.location) + ".."
157 + Locations.endOf(token.location) + "]");*/
159 } catch(Exception e) {
160 if(e instanceof RuntimeException)
161 throw (RuntimeException)e;
163 throw new RuntimeException(e);
168 protected Object reduceDeclarations() {
169 ArrayList<DeclarationAst> declarations = new ArrayList<DeclarationAst>(length()/2);
170 for(int i=1;i<length();i+=2)
171 declarations.add((DeclarationAst)get(i));
176 protected Object reduceModule() {
177 ArrayList<DeclarationAst> declarations = new ArrayList<DeclarationAst>(length()/2+1);
178 for(int i=0;i<length();i+=2) {
179 DeclarationAst declaration = (DeclarationAst)get(i);
180 if(declaration == null)
182 declarations.add(declaration);
188 protected Object reduceModuleHeader() {
189 FieldAssignment[] fields = new FieldAssignment[length()/2-1];
190 for(int i=0;i<fields.length;++i)
191 fields[i] = (FieldAssignment)get(2+i*2);
192 context.header = ModuleHeader.process(context.errorLog, fields);
197 protected Object reduceLocalTypeAnnotation() {
200 return new ETypeAnnotation((Expression)get(0), (TypeAst)get(2));
204 protected Object reduceTypeAnnotation() {
205 EVar[] names = new EVar[length()/2];
206 for(int i=0;i<names.length;++i)
207 names[i] = (EVar)get(i*2);
208 return new DValueTypeAst(
210 (TypeAst)get(length()-1)
215 protected Object reduceValueDefinition() {
216 Expression rhs = (Expression)get(1);
217 return new DValueAst((Expression)get(0), rhs);
221 protected Object reduceDataDefinition() {
223 ArrayList<String> parameters = new ArrayList<String>();
224 while(i < length()) {
225 Token token = (Token)get(i++);
226 if(token.id != SCLTerminals.ID)
228 parameters.add(token.text);
230 ArrayList<ConstructorAst> constructors = new ArrayList<ConstructorAst>();
231 for(;i < length();i+=2)
232 constructors.add((ConstructorAst)get(i));
234 ((Token)get(1)).text,
235 parameters.toArray(new String[parameters.size()]),
236 constructors.toArray(new ConstructorAst[constructors.size()]),
242 protected Object reduceTypeDefinition() {
244 ArrayList<String> parameters = new ArrayList<String>();
246 Token token = (Token)get(i++);
247 if(token.id != SCLTerminals.ID)
249 parameters.add(token.text);
252 ((Token)get(1)).text,
253 parameters.toArray(new String[parameters.size()]),
258 @SuppressWarnings("unchecked")
260 protected Object reduceClassDefinition() {
262 ArrayList<TypeAst> context;
263 if(get(i) instanceof Token)
264 context = new ArrayList<TypeAst>(0);
266 context = (ArrayList<TypeAst>)get(i++);
267 String name = ((Token)get(i++)).text;
268 ArrayList<String> parameters = new ArrayList<String>();
269 while(i < length()) {
270 Token token = (Token)get(i);
271 if(token.id != SCLTerminals.ID)
273 parameters.add(token.text);
276 ArrayList<DeclarationAst> declarations = null;
277 FundepAst[] fundeps = FundepAst.EMPTY_ARRAY;
278 while(i < length()) {
279 Token token = (Token)get(i++);
280 if(token.id == SCLTerminals.WHERE) {
281 declarations = (ArrayList<DeclarationAst>)get(i++);
283 else if(token.id == SCLTerminals.BAR) {
284 fundeps = (FundepAst[])get(i++);
287 throw new InternalCompilerError();
289 return new DClassAst(context, name,
290 parameters.toArray(new String[parameters.size()]),
296 protected Object reduceFundep() {
297 String[] from = new String[length()-2];
298 for(int i=0;i<from.length;++i)
299 from[i] = ((Token)get(i)).text;
300 String to = ((Token)get(length()-1)).text;
301 return new FundepAst(from, to);
305 protected Object reduceFundeps() {
306 FundepAst[] fundeps = new FundepAst[(length()+1)/2];
307 for(int i=0;i<fundeps.length;++i)
308 fundeps[i] = (FundepAst)get(i*2);
312 @SuppressWarnings("unchecked")
314 protected Object reduceInstanceDefinition() {
316 ArrayList<TypeAst> context;
317 if(get(i) instanceof Token)
318 context = new ArrayList<TypeAst>(0);
320 context = (ArrayList<TypeAst>)get(i++);
321 Token nameToken = (Token)get(i++);
322 EVar name = new EVar(nameToken);
323 ArrayList<TypeAst> parameters = new ArrayList<TypeAst>();
324 while(i < length()) {
325 Object symbol = get(i++);
326 if(symbol instanceof Token)
328 parameters.add((TypeAst)symbol);
330 ArrayList<DeclarationAst> declarations = null;
332 declarations = (ArrayList<DeclarationAst>)get(i);
333 return new DInstanceAst(context, name,
334 parameters.toArray(new TypeAst[parameters.size()]),
338 @SuppressWarnings("unchecked")
340 protected Object reduceDerivingInstanceDefinition() {
342 ArrayList<TypeAst> context;
343 if(get(i) instanceof Token)
344 context = new ArrayList<TypeAst>(0);
346 context = (ArrayList<TypeAst>)get(i++);
347 Token nameToken = (Token)get(i++);
348 EVar name = new EVar(nameToken);
349 ArrayList<TypeAst> parameters = new ArrayList<TypeAst>();
350 while(i < length()) {
351 Object symbol = get(i++);
352 parameters.add((TypeAst)symbol);
354 return new DDerivingInstanceAst(context, name,
355 parameters.toArray(new TypeAst[parameters.size()]));
359 protected Object reduceDocumentationString() {
360 return new DDocumentationAst(((Token)get(1)).text);
364 protected Object reduceAnnotation() {
365 ArrayList<Expression> parameters = new ArrayList<Expression>(length()-1);
366 for(int i=1;i<length();++i)
367 parameters.add((Expression)get(i));
368 return new DAnnotationAst((Token)get(0), parameters);
372 protected Object reducePrecedenceDefinition() {
373 EVar[] symbols = new EVar[length()/2];
374 for(int i=0;i<symbols.length;++i)
375 symbols[i] = (EVar)get(2*i + 2);
376 Associativity associativity;
377 Token token = (Token)get(0);
378 if(token.text.equals("infixl"))
379 associativity = Associativity.LEFT;
380 else if(token.text.equals("infixr"))
381 associativity = Associativity.RIGHT;
383 associativity = Associativity.NONASSOC;
384 return new DFixityAst(
386 Integer.parseInt(((Token)get(1)).text),
392 protected Object reduceImport() {
393 // (AS ID)? importSpec?
395 String importKeyword = ((Token)get(pos++)).text; // (IMPORT | INCLUDE)
396 ++pos; // BEGIN_STRING
397 String moduleName = ((Token)get(pos++)).text; // END_STRING
398 String localName = "";
400 Object temp = get(pos);
401 if(temp instanceof Token) {
402 Token token = (Token)temp;
403 if(token.id == SCLTerminals.AS) {
405 localName = ((Token)get(pos++)).text; // ID
409 ImportDeclaration.ImportSpec spec = ImportDeclaration.DEFAULT_SPEC;
411 spec = (ImportDeclaration.ImportSpec)get(pos++);
412 return new ImportDeclaration(moduleName, localName,
413 importKeyword.equals("include"),
418 protected Object reduceJustImport() {
422 @SuppressWarnings("unchecked")
424 protected Object reduceImportJava() {
425 return new DImportJavaAst(((Token)get(2)).text, (ArrayList<DeclarationAst>)get(4));
429 protected Object reduceEffectDefinition() {
430 return new DEffectAst(
431 ((Token)get(1)).text,
432 ((Token)get(3)).text,
433 ((Token)get(5)).text);
437 protected Object reduceVarId() {
438 return new EVar((Token)get(0));
442 protected Object reduceEscapedSymbol() {
443 return new EVar((Token)get(0));
447 protected Object reduceTupleTypeConstructor() {
448 return new TVarAst(Types.tupleConstructor(length()-1).name);
452 protected Object reduceArrow() {
454 TypeAst result = (TypeAst)get(i);
457 if( ((Token)get(i+1)).text.equals("=>") )
458 result = new TPredAst((TypeAst)get(i), result);
460 result = new TFunctionAst((TypeAst)get(i), result);
467 protected Object reduceBinary() {
471 EVar negation = null;
472 if(get(i) instanceof Token) {
473 Token token = (Token)get(i++);
474 negation = new EVar(token);
476 EBinary binary = new EBinary((Expression)get(i++), negation);
477 while(i < length()) {
478 EVar operator = (EVar)get(i++);
479 Expression right = (Expression)get(i++);
480 binary.rights.add(new EBinaryRightSide(operator, right));
486 protected Object reduceSimpleRhs() {
490 EBlock block = (EBlock)get(3);
491 Expression expression = (Expression)get(1);
492 block.addStatement(new GuardStatement(expression));
493 block.location = Locations.location(Locations.beginOf(expression.location), Locations.endOf(block.location));
498 private GuardedExpressionGroup reduceGuardedExpressionGroup(int length) {
499 GuardedExpression[] expressions = new GuardedExpression[length];
500 for(int i=0;i<expressions.length;++i) {
501 expressions[i] = (GuardedExpression)get(i);
503 return new GuardedExpressionGroup(expressions);
507 protected Object reduceGuardedRhs() {
508 int length = length();
509 if(length > 2 && get(length-2) instanceof Token) {
510 EBlock block = (EBlock)get(length-1);
511 block.addStatement(new GuardStatement(reduceGuardedExpressionGroup(length-2)));
512 block.location = Locations.NO_LOCATION;
516 return reduceGuardedExpressionGroup(length);
520 protected Object reduceStatements() {
521 EBlock block = new EBlock();
523 for(int i=1;i<length();i+=2)
524 block.addStatement((Statement)get(i));
529 protected Object reduceConstructor() {
531 for(idPos=0;idPos<length();idPos+=2)
532 if(((Token)get(idPos)).id == SCLTerminals.ID)
534 DAnnotationAst[] annotations = idPos == 0 ? DAnnotationAst.EMPTY_ARRAY : new DAnnotationAst[idPos/2];
535 for(int i=0;i<idPos/2;++i)
536 annotations[i] = new DAnnotationAst((Token)get(i*2),
537 Arrays.asList((Expression)get(i*2+1)));
538 TypeAst[] parameters = new TypeAst[length()-idPos-1];
539 for(int i=0;i<parameters.length;++i)
540 parameters[i] = (TypeAst)get(i+idPos+1);
541 return new ConstructorAst(annotations, (Token)get(idPos), parameters, null);
545 protected Object reduceContext() {
546 ArrayList<TypeAst> result = new ArrayList<TypeAst>(length()/2-1);
547 for(int i=1;i<length()-2;i+=2)
548 result.add((TypeAst)get(i));
553 protected Object reduceTypeVar() {
554 return new TVarAst(((Token)get(0)).text);
558 protected Object reduceTupleType() {
560 return new TTupleAst(TypeAst.EMPTY_ARRAY);
562 Symbol sym = (Symbol)get(1);
563 sym.location = Locations.NO_LOCATION;
566 int dim = length()/2;
567 TypeAst[] parameters = new TypeAst[dim];
568 for(int i=0;i<dim;++i)
569 parameters[i] = (TypeAst)get(i*2+1);
570 return new TTupleAst(parameters);
574 protected Object reduceListType() {
575 return new TListAst((TypeAst)get(1));
579 protected Object reduceListTypeConstructor() {
580 return new TVarAst("[]");
584 protected Object reduceTupleConstructor() {
585 return new EVar(Types.tupleConstructor(length()-1).name);
589 protected Object reduceVar() {
594 protected Object reduceBlank() {
595 return new EVar(((Token)get(0)).location, "_");
599 protected Object reduceInteger() {
600 return new EIntegerLiteral(((Token)get(0)).text);
604 protected Object reduceFloat() {
605 return new ERealLiteral(((Token)get(0)).text);
609 protected Object reduceString() {
614 protected Object reduceChar() {
615 String text = ((Token)get(0)).text;
616 char c = text.charAt(text.length()-2);
617 if(text.length() == 4) {
619 case 'n': c = '\n'; break;
620 case 't': c = '\t'; break;
621 case 'b': c = '\b'; break;
622 case 'f': c = '\f'; break;
623 case 'r': c = '\r'; break;
626 return new ELiteral(new CharacterConstant(c));
630 protected Object reduceTuple() {
632 return new EConstant(Builtins.TUPLE_CONSTRUCTORS[0]);
634 Symbol sym = (Symbol)get(1);
635 sym.location = Locations.NO_LOCATION;
638 int dim = length()/2;
639 Expression[] parameters = new Expression[dim];
640 for(int i=0;i<dim;++i)
641 parameters[i] = (Expression)get(i*2+1);
642 EConstant tupleConstructor = new EConstant(Builtins.TUPLE_CONSTRUCTORS[dim]);
643 tupleConstructor.location = Locations.location(
644 Locations.beginOf(((Token)get(0)).location),
645 Locations.endOf(((Token)get(length()-1)).location));
646 return new EApply(tupleConstructor, parameters);
649 public static Expression rightSection(EVar op, Expression e) {
650 long loc = Locations.combine(op.location, e.location);
651 Variable var = new Variable("rightSectionTemp");
652 return new ESimpleLambda(loc, var,
653 new EApply(loc, op, new EVariable(loc, var), e));
657 protected Object reduceRightSection() {
658 Variable var = new Variable("rightSectionTemp");
659 long loc = Locations.combine(((Token)get(0)).location, ((Token)get(length()-1)).location);
660 EVar symbol = (EVar)get(1);
661 return new ESimpleLambda(var,
662 new EApply(loc, symbol,
663 new EVariable(loc, var), (Expression)get(2)));
667 protected Object reduceLeftSection() {
668 return new EApply((EVar)get(2), (Expression)get(1));
672 protected Object reduceListLiteral() {
674 return new EListLiteral(Expression.EMPTY_ARRAY);
675 int dim = length()/2;
676 Expression[] components = new Expression[dim];
677 for(int i=0;i<dim;++i)
678 components[i] = (Expression)get(i*2+1);
679 return new EListLiteral(components);
683 protected Object reduceRange() {
691 protected Object reduceListComprehension() {
692 ListQualifier qualifier = (ListQualifier)get(3);
693 for(int i=5;i<length();i+=2) {
694 ListQualifier right = (ListQualifier)get(i);
695 if(right instanceof ListThen) {
696 ((ListThen) right).setLeft(qualifier);
700 qualifier = new ListSeq(qualifier, right);
702 return new EListComprehension((Expression)get(1), qualifier);
706 protected Object reduceAs() {
707 Token id = (Token)get(0);
708 return new EAsPattern(new EVar(id.location, id.text), (Expression)get(2));
712 protected Object reduceGuardedExpEq() {
713 Expression[] guards = new Expression[length()/2-1];
714 for(int i=0;i<guards.length;++i)
715 guards[i] = (Expression)get(i*2+1);
716 return new GuardedExpression(guards, (Expression)get(length()-1));
720 protected Object reduceLambda() {
721 Expression[] patterns = new Expression[length()-3];
722 for(int i=0;i<patterns.length;++i)
723 patterns[i] = (Expression)get(i+1);
724 Case case_ = new Case(patterns, (Expression)get(length()-1));
725 case_.setLhs(Locations.combine(patterns[0].location, patterns[patterns.length-1].location));
726 return new ELambda(case_);
730 protected Object reduceLambdaMatch() {
731 Case[] cases = new Case[length()/2-1];
732 for(int i=0;i<cases.length;++i)
733 cases[i] = (Case)get(i*2+2);
734 return new ELambda(cases);
738 protected Object reduceLet() {
739 EBlock block = (EBlock)get(1);
740 Expression expression = (Expression)get(3);
741 block.addStatement(new GuardStatement(expression));
742 Token letToken = (Token)get(0);
743 block.location = Locations.location(
744 Locations.beginOf(letToken.location),
745 Locations.endOf(expression.location));
750 protected Object reduceIf() {
754 length() == 6 ? (Expression)get(5) : null);
758 protected Object reduceMatch() {
759 Case[] cases = new Case[length()/2-2];
760 for(int i=0;i<cases.length;++i)
761 cases[i] = (Case)get(i*2+4);
762 return new EMatch((Expression)get(1), cases);
766 protected Object reduceDo() {
767 EBlock block = (EBlock)get(1);
768 Token doToken = (Token)get(0);
769 switch(doToken.text) {
771 block.setBlockType(BlockType.Monad);
774 block.setBlockType(BlockType.MonadE);
777 block.location = Locations.location(Locations.beginOf(doToken.location), Locations.endOf(block.location));
782 protected Object reduceSelect() {
783 return new ESelect(((Token)get(0)).id, (Expression)get(1), new QConjunction((Query[])get(3)));
787 protected Object reduceEnforce() {
788 return new EEnforce(new QConjunction((Query[])get(1)));
792 protected Object reduceApply() {
795 Expression[] parameters = new Expression[length()-1];
796 for(int i=0;i<parameters.length;++i)
797 parameters[i] = (Expression)get(i+1);
798 return new EApply((Expression)get(0), parameters);
802 protected Object reduceSymbol() {
803 return new EVar(((Token)get(0)).text);
807 protected Object reduceEscapedId() {
808 return new EVar(((Token)get(0)).text);
812 protected Object reduceMinus() {
813 return new EVar(((Token)get(0)).text);
817 protected Object reduceLess() {
818 return new EVar(((Token)get(0)).text);
822 protected Object reduceGreater() {
823 return new EVar(((Token)get(0)).text);
827 protected Object reduceDot() {
828 return new EVar(((Token)get(0)).text);
832 protected Object reduceCase() {
833 return new Case((Expression)get(0), (Expression)get(1));
837 protected Object reduceGuardQualifier() {
838 return new ListGuard((Expression)get(0));
842 protected Object reduceLetQualifier() {
843 return new ListAssignment((Expression)get(0), (Expression)get(2));
847 protected Object reduceBindQualifier() {
848 return new ListGenerator((Expression)get(0), (Expression)get(2));
852 protected Object reduceThenQualifier() {
853 return new ListThen((Expression)get(1), length()==4 ? (Expression)get(3) : null);
857 protected Object reduceGuardStatement() {
858 return new GuardStatement((Expression)get(0));
862 protected Object reduceLetStatement() {
863 return new LetStatement((Expression)get(0), (Expression)get(1));
867 protected Object reduceBindStatement() {
868 return new BindStatement((Expression)get(0), (Expression)get(2));
872 protected Object reduceSimpleCaseRhs() {
877 protected Object reduceGuardedCaseRhs() {
878 GuardedExpression[] expressions = new GuardedExpression[length()];
879 for(int i=0;i<expressions.length;++i)
880 expressions[i] = (GuardedExpression)get(i);
881 return new GuardedExpressionGroup(expressions);
885 protected Object reduceGuardedExpArrow() {
886 Expression[] guards = new Expression[length()/2-1];
887 for(int i=0;i<guards.length;++i)
888 guards[i] = (Expression)get(i*2+1);
889 return new GuardedExpression(guards, (Expression)get(length()-1));
893 protected Object reduceEffect() {
894 ArrayList<TypeAst> effects = new ArrayList<TypeAst>(length()/2-1);
895 for(int i=1;i<length()-1;i+=2) {
896 Token token = (Token)get(i);
897 TVarAst ast = new TVarAst(token.text);
898 ast.location = token.location;
901 return new TEffectAst(effects, (TypeAst)get(length()-1));
905 protected Object reduceJustEtype() {
910 protected Object reduceForAll() {
911 String[] vars = new String[length()-3];
912 for(int i=0;i<vars.length;++i)
913 vars[i] = ((Token)get(i+1)).text;
914 return new TForAllAst(vars, (TypeAst)get(length()-1));
918 protected Object reduceApplyType() {
919 TypeAst[] parameters = new TypeAst[length()-1];
920 for(int i=0;i<parameters.length;++i)
921 parameters[i] = (TypeAst)get(i+1);
922 return new TApplyAst((TypeAst)get(0), parameters);
925 @SuppressWarnings("unchecked")
927 protected void postReduce(Object reduced) {
928 if(!(reduced instanceof Symbol))
930 Symbol sym = (Symbol)reduced;
931 if(sym.location != Locations.NO_LOCATION || length() == 0)
933 Object first = get(0);
934 if(!(first instanceof Symbol)) {
935 if(first instanceof List) {
936 List<Object> ll = (List<Object>)first;
940 Object[] ll = (Object[])first;
947 Object last = get(length()-1);
948 if(!(last instanceof Symbol)) {
949 if(last instanceof List) {
950 List<Object> ll = (List<Object>)last;
951 last = ll.get(ll.size()-1);
954 Object[] ll = (Object[])last;
956 last = ll[ll.length-1];
958 last = get(length()-2);
961 sym.location = (((Symbol)first).location & 0xffffffff00000000L)
962 | (((Symbol)last).location & 0xffffffffL);
963 /*for(int i=0;i<length();++i) {
965 System.out.print(obj.getClass().getSimpleName());
966 if(obj instanceof Token) {
967 Token t = (Token)obj;
968 System.out.print("(" + t.text + ")");
970 if(obj instanceof Symbol) {
971 Symbol s = (Symbol)obj;
972 System.out.print("["+ Locations.beginOf(s.location) + "-" + Locations.endOf(s.location) + "]");
974 System.out.print(" ");
976 System.out.println("-> " + reduced.getClass().getSimpleName() + " " +
977 Locations.beginOf(sym.location) + "-" + Locations.endOf(sym.location));*/
981 protected RuntimeException syntaxError(Token token, String description) {
982 throw new SCLSyntaxErrorException(token.location, description);
986 protected Object reduceIdAccessor() {
987 return new IdAccessor('.', ((Token)get(0)).text);
991 protected Object reduceStringAccessor() {
992 return new StringAccessor('.', ((Token)get(1)).text);
996 protected Object reduceExpAccessor() {
997 return new ExpressionAccessor('.', (Expression)get(1));
1001 protected Object reduceFieldAccess() {
1004 Expression result = (Expression)get(0);
1005 for(int i=2;i<length();i+=2) {
1006 FieldAccessor accessor = (FieldAccessor)get(i);
1007 accessor.accessSeparator = ((Token)get(i-1)).text.charAt(0);
1008 result = new EFieldAccess(result, accessor);
1014 protected Object reduceQueryBlock() {
1016 return Query.EMPTY_ARRAY;
1017 Query[] queries = new Query[length()/2];
1018 for(int i=0;i<queries.length;++i)
1019 queries[i] = (Query)get(2*i+1);
1024 protected Object reduceGuardQuery() {
1025 return new QPreGuard((Expression)get(0));
1029 protected Object reduceEqualsQuery() {
1030 return new QPreEquals((Expression)get(0), (Expression)get(2));
1034 protected Object reduceBindQuery() {
1035 return new QPreBinds((Expression)get(0), (Expression)get(2));
1039 protected Object reduceCompositeQuery() {
1040 Query[] queries = (Query[])get(1);
1041 switch(((Token)get(0)).text.charAt(1)) {
1042 case '&': return new QConjunction(queries);
1043 case '|': return new QDisjunction(queries);
1044 case '!': return new QNegation(new QConjunction(queries));
1045 case '?': return new QAlternative(queries);
1046 default: throw new InternalCompilerError();
1051 protected Object reduceRuleStatement() {
1052 return new RuleStatement((Expression)get(0), new QConjunction((Query[])get(2)));
1056 protected Object reduceHashedId() {
1057 return new EVar("#" + ((Token)get(1)).text);
1061 protected Object reduceStringLiteral() {
1062 int expCount = length()/3;
1064 return new ELiteral(new StringConstant(((Token)get(1)).text));
1066 String[] strings = new String[expCount+1];
1067 Expression[] expressions = new Expression[expCount];
1068 for(int i=0;i<expCount;++i) {
1069 strings[i] = ((Token)get(i*3+1)).text;
1070 expressions[i] = (Expression)get(i*3+2);
1072 strings[expCount] = ((Token)get(expCount*3+1)).text;
1073 return new EStringLiteral(strings, expressions);
1078 protected Object reduceOneCommand() {
1083 protected Object reduceManyCommands() {
1088 protected Object reduceStatementCommand() {
1089 // to be extended in subclasses
1094 protected Object reduceImportCommand() {
1095 // to be extended in subclasses
1100 protected Object reduceImportValueItem() {
1101 return new EVar(((Token)get(0)).text);
1105 protected Object reduceImportHiding() {
1106 EVar[] values = new EVar[(length()-2)/2];
1107 for(int i=0;i<values.length;++i)
1108 values[i] = (EVar)get(i*2+2);
1109 return new ImportDeclaration.ImportSpec(true, values);
1113 protected Object reduceImportShowing() {
1114 EVar[] values = new EVar[(length()-1)/2];
1115 for(int i=0;i<values.length;++i)
1116 values[i] = (EVar)get(i*2+1);
1117 return new ImportDeclaration.ImportSpec(false, values);
1121 protected Object reduceRuleDeclarations() {
1122 ArrayList<Object> declarations = new ArrayList<Object>(length()/2);
1123 for(int i=1;i<length();i+=2)
1124 declarations.add((Object)get(i));
1125 return declarations;
1128 private static final String[] EMPTY_STRING_ARRAY = new String[0];
1130 @SuppressWarnings("unchecked")
1132 protected Object reduceRuleDefinition() {
1133 String[] extendsNames = EMPTY_STRING_ARRAY;
1135 int extendsCount = (length() - 4) / 2;
1136 extendsNames = new String[extendsCount];
1137 for(int i=0;i<extendsCount;++i)
1138 extendsNames[i] = ((Token)get(3+i*2)).text;
1141 DRuleAst rule = new DRuleAst(
1142 ((Token)get(0)).id == SCLTerminals.ABSTRACT_RULE,
1143 ((Token)get(1)).text,
1146 ArrayList<Object> ruleDeclarations = (ArrayList<Object>)get(length()-1);
1147 ArrayList<Query> section = null;
1148 for(Object decl : ruleDeclarations) {
1149 if(decl instanceof DAnnotationAst) {
1150 DAnnotationAst annotation = (DAnnotationAst)decl;
1151 section = rule.getSection(annotation.id.text.substring(1));
1153 else if(decl instanceof Query) {
1155 section = rule.getSection("when");
1156 section.add((Query)decl);
1159 throw new InternalCompilerError();
1165 protected Object reduceQueryRuleDeclaration() {
1170 protected Object reduceMappingRelationDefinition() {
1171 TypeAst[] types = new TypeAst[length()-2];
1172 for(int i=0;i<types.length;++i)
1173 types[i] = (TypeAst)get(i+2);
1174 return new DMappingRelationAst(
1175 ((Token)get(1)).text,
1180 protected Object reduceTransformation() {
1181 return new ETransformation(
1182 ((Token)get(1)).text,
1183 new QConjunction((Query[])get(3))
1187 @SuppressWarnings("unchecked")
1189 protected Object reduceRelationDefinition() {
1190 return new DRelationAst((Expression)get(0),
1191 ((ArrayList<Object>)get(2)).toArray());
1195 protected Object reduceRecord() {
1196 FieldAssignment[] fields = new FieldAssignment[length()/2-1];
1197 for(int i=0;i<fields.length;++i)
1198 fields[i] = (FieldAssignment)get(2+i*2);
1199 return new ERecord(new EVar((Token)get(0)), fields);
1203 protected Object reduceField() {
1204 return new FieldAssignment(((Token)get(0)).text, (Expression)get(2));
1208 protected Object reduceFieldShorthand() {
1209 return new FieldAssignment(((Token)get(0)).text, null);
1213 protected Object reduceRecordConstructor() {
1215 for(idPos=0;idPos<length();idPos+=2)
1216 if(((Token)get(idPos)).id == SCLTerminals.ID)
1218 DAnnotationAst[] annotations = idPos == 0 ? DAnnotationAst.EMPTY_ARRAY : new DAnnotationAst[idPos/2];
1219 for(int i=0;i<idPos/2;++i)
1220 annotations[i] = new DAnnotationAst((Token)get(i*2),
1221 Arrays.asList((Expression)get(i*2+1)));
1222 TypeAst[] parameters = new TypeAst[(length()-idPos-1)/2];
1223 String[] fieldNames = new String[parameters.length];
1224 for(int i=0;i<parameters.length;++i) {
1225 FieldDescription fieldDesc = (FieldDescription)get(idPos+(i+1)*2);
1226 parameters[i] = fieldDesc.type;
1227 fieldNames[i] = fieldDesc.name;
1229 return new ConstructorAst(annotations, (Token)get(idPos), parameters, fieldNames);
1233 protected Object reduceFieldDescription() {
1234 return new FieldDescription(((Token)get(0)).text, (TypeAst)get(2));
1238 protected Object reduceEq() {
1239 return (Expression)get(2);
1243 protected Object reduceEquationBlock() {
1245 return new EEquations(Equation.EMPTY_ARRAY);
1246 Equation[] equations = new Equation[length()/2+1];
1247 for(int i=0;i<equations.length;++i)
1248 equations[i] = (Equation)get(2*i);
1249 return new EEquations(equations);
1253 protected Object reduceGuardEquation() {
1254 return new EqGuard((Expression)get(0));
1258 protected Object reduceBasicEquation() {
1259 return new EqBasic((Expression)get(0), (Expression)get(2));
1263 protected Object reduceViewPattern() {
1264 return new EViewPattern((Expression)get(1), (Expression)get(3));
1268 protected Object reduceConstraintStatement() {
1269 ConstructorAst constructor = (ConstructorAst)get(1);
1270 return new ConstraintStatement(constructor.name, constructor.parameters, constructor.fieldNames, constructor.annotations);
1275 protected Object reduceWhen() {
1277 new QConjunction((Query[])get(1)),
1278 (Expression)get(3));
1282 protected Object reduceDummy() {
1283 throw new UnsupportedOperationException();
1287 protected Object reduceRulesetDefinition() {
1288 Token name = (Token)get(1);
1289 EBlock block = (EBlock)get(3);
1290 return new DRulesetAst(name.text, block);
1294 protected Object reduceLocalInclude() {
1295 Token name = (Token)get(1);
1296 Expression value = (Expression)get(2);
1297 return new IncludeStatement(name, value);
1301 protected Object reduceConstraintSpec() {
1302 Expression[] expressions = new Expression[length()/2-1];
1303 for(int i=0;i<expressions.length;++i)
1304 expressions[i] = (Expression)get(2*i+1);
1309 protected Object reduceCHRSelect() {
1310 return new EPreCHRSelect((CHRAstQuery)get(3), (Expression)get(1));
1314 protected Object reduceCHRAtom() {
1315 return CHRAstAtom.atom((Expression)get(0));
1319 protected Object reduceCHREquals() {
1320 return new CHRAstEquals((Expression)get(0), (Expression)get(2));
1324 protected Object reduceCHRBinds() {
1325 return new CHRAstBinds((Expression)get(0), (Expression)get(2));
1329 protected Object reduceCHRConjunction() {
1330 CHRAstQuery[] conjuncts = new CHRAstQuery[(length()+1)/2];
1331 for(int i=0;i<conjuncts.length;++i)
1332 conjuncts[i] = (CHRAstQuery)get(i*2);
1333 return CHRAstConjunction.conjunction(conjuncts);
1337 protected Object reduceVerboseCHRConjunction() {
1338 CHRAstQuery[] conjuncts = new CHRAstQuery[(length()-1)/2];
1339 for(int i=0;i<conjuncts.length;++i)
1340 conjuncts[i] = (CHRAstQuery)get(i*2+1);
1341 return CHRAstConjunction.conjunction(conjuncts);
1345 protected Object reduceVerboseCHRStatement() {
1346 return new CHRStatement((CHRAstQuery)get(1), (CHRAstQuery)get(3));
1350 protected Object reduceCHRStatement() {
1351 return new CHRStatement((CHRAstQuery)get(0), (CHRAstQuery)get(2));
1355 protected Object reduceWildcard() {
1356 return new FieldAssignment(FieldAssignment.WILDCARD, null);