X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Finternal%2Fparsing%2Fparser%2FSCLPostLexer.java;h=a2253d8b7bc001cc7d0889a5ab69a0a5885e7922;hp=866fb8c985c4126b6e368746b83c767953c66cda;hb=78f577368ba4c71ad6fb3d9f16c03c634585cf7b;hpb=6ceab2d9498554c1b825ab6ae76bef520bb05789 diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLPostLexer.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLPostLexer.java index 866fb8c98..a2253d8b7 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLPostLexer.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLPostLexer.java @@ -3,6 +3,7 @@ package org.simantics.scl.compiler.internal.parsing.parser; import java.io.IOException; import java.util.Arrays; +import org.simantics.scl.compiler.compilation.CompilationContext; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.parsing.Token; import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException; @@ -16,6 +17,9 @@ import gnu.trove.set.hash.TIntHashSet; * @author Hannu Niemistö */ public class SCLPostLexer { + + private static final int PATCH_SIZE = 16; + private static final int INITIAL_QUEUE_SIZE = 32; public static TIntHashSet INDENTABLE = new TIntHashSet(); public static TIntHashSet NO_SEMICOLON_BEFORE = new TIntHashSet(); @@ -31,6 +35,8 @@ public class SCLPostLexer { INDENTABLE.add(SCLTerminals.WHEN); INDENTABLE.add(SCLTerminals.FOLLOWS); INDENTABLE.add(SCLTerminals.EQ); + INDENTABLE.add(SCLTerminals.LAMBDA_MATCH); + INDENTABLE.add(SCLTerminals.THEN_AFTER_WHEN); NO_SEMICOLON_BEFORE.add(SCLTerminals.EOF); NO_SEMICOLON_BEFORE.add(SCLTerminals.SYMBOL); @@ -40,22 +46,32 @@ public class SCLPostLexer { NO_SEMICOLON_BEFORE.add(SCLTerminals.RBRACE); NO_SEMICOLON_BEFORE.add(SCLTerminals.RBRACKET); NO_SEMICOLON_BEFORE.add(SCLTerminals.RPAREN); + NO_SEMICOLON_BEFORE.add(SCLTerminals.SEMICOLON); NO_SEMICOLON_AFTER.add(SCLTerminals.EOF); NO_SEMICOLON_AFTER.add(SCLTerminals.SYMBOL); } SCLLexer lexer; - Token[] queue = new Token[16]; + Token[] queue = new Token[INITIAL_QUEUE_SIZE]; int queuePos=0, queueSize=0; TIntArrayList indentations = new TIntArrayList(); + TIntArrayList indentationTokens = new TIntArrayList(); Token curToken = null; int lineStart = 0; boolean firstTokenOfLine = true; private SCLParserOptions options; + private boolean isFirstToken = true; + private CompilationContext context; + + /** + * We are parsing a module header and therefore should process tokens one by one and not by patches. + */ + private boolean isInsideModule = false; { indentations.add(0); + indentationTokens.add(SCLTerminals.EOF); } public SCLPostLexer(SCLLexer lexer) { @@ -65,6 +81,11 @@ public class SCLPostLexer { public SCLPostLexer(java.io.Reader in) { this(new SCLLexer(in)); } + + public void setCompilationContext(CompilationContext context) { + lexer.setCompilationContext(context); + this.context = context; + } public Token nextToken() throws Exception { while(queuePos == queueSize) @@ -92,8 +113,15 @@ public class SCLPostLexer { queuePos = 0; queueSize = 0; - for(int i=0;i<8;++i) + for(int i=0;i= 0) { - int loc = Locations.endOf(prevToken.location); - push(new Token(SCLTerminals.RBRACE, loc, loc, "implicit }")); - } - if(indentations.isEmpty()) - throw error(symbolStart, symbolEnd, "No corresponding opening parenthesis for '" + symbol.text + "'."); - push(symbol); - return; - case SCLTerminals.THEN: // 'then' both closes and opens a block - while(!indentations.isEmpty() && indentations.removeAt(indentations.size()-1) >= 0) { - int loc = Locations.endOf(prevToken.location); - push(new Token(SCLTerminals.RBRACE, loc, loc, "implicit }")); + int removedToken = SCLTerminals.EOF; + while(!indentations.isEmpty()) { + removedToken = indentationTokens.removeAt(indentations.size()-1); + //System.out.println(" removed " + SCLParser.TERMINAL_NAMES[removedToken]); + if(indentations.removeAt(indentations.size()-1) < 0) + break; + long loc = prevToken != null ? Locations.location(Locations.endOf(prevToken.location), Locations.endOf(prevToken.location)) : symbol.location; + push(new Token(SCLTerminals.RBRACE, loc, "implicit }")); } if(indentations.isEmpty()) throw error(symbolStart, symbolEnd, "No corresponding opening parenthesis for '" + symbol.text + "'."); + if(symbolId == SCLTerminals.THEN) { + if(removedToken == SCLTerminals.WHEN) + curToken = symbol = new Token(SCLTerminals.THEN_AFTER_WHEN, symbol.location, symbol.text); + else { + indentations.add(-1); + indentationTokens.add(SCLTerminals.THEN); + } + } push(symbol); - indentations.add(-1); return; case SCLTerminals.EOF: while(indentations.size() > 1 && indentations.get(indentations.size()-1) >= 0) { - int loc = Locations.endOf(prevToken.location); - push(new Token(SCLTerminals.RBRACE, loc, loc, "implicit }")); + long loc = prevToken != null ? Locations.location(Locations.endOf(prevToken.location), Locations.endOf(prevToken.location)) : symbol.location; + push(new Token(SCLTerminals.RBRACE, loc, "implicit }")); + indentationTokens.removeAt(indentations.size()-1); indentations.removeAt(indentations.size()-1); } if(indentations.size() > 1)