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=9cc1ff27b16a288afb11f138b9d8755a84f642d0;hp=4a446e6e2f2027af55c80c9fbd06da7cd30f8200;hb=c26409b1caf2f1e560d37c5befd11b442399c3fe;hpb=969bd23cab98a79ca9101af33334000879fb60c5 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 4a446e6e2..9cc1ff27b 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 @@ -31,6 +31,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,6 +42,7 @@ 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); @@ -49,13 +52,16 @@ public class SCLPostLexer { Token[] queue = new Token[16]; 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; { indentations.add(0); + indentationTokens.add(SCLTerminals.EOF); } public SCLPostLexer(SCLLexer lexer) { @@ -79,6 +85,10 @@ public class SCLPostLexer { } private void push(Token symbol) { + /*System.out.println("TOKEN " + symbol.text + " (" + SCLParser.TERMINAL_NAMES[symbol.id] + ")" + + " [" + + Locations.beginOf(symbol.location) + ".." + + Locations.endOf(symbol.location) + "]");*/ if(queueSize == queue.length) queue = Arrays.copyOf(queue, queueSize*2); queue[queueSize++] = symbol; @@ -117,12 +127,11 @@ public class SCLPostLexer { int symbolEnd = Locations.endOf(symbol.location); if(INDENTABLE.contains(prevTokenId) && symbolId != SCLTerminals.LBRACE) { - if(prevTokenId == SCLTerminals.LET) - indentations.add(-1); push(new Token(SCLTerminals.LBRACE, symbolStart, symbolStart, "implicit {")); int symbolIndentation = symbolStart-lineStart; //System.out.println("symbolIndentation = " + symbolIndentation); indentations.add(symbolIndentation); + indentationTokens.add(prevTokenId); firstTokenOfLine = false; } else if(firstTokenOfLine) { @@ -133,6 +142,7 @@ public class SCLPostLexer { //System.out.println("level = " + level); if(indentations.get(indentations.size()-1) >= level) { while(indentations.get(indentations.size()-1) > level) { + indentationTokens.removeAt(indentations.size()-1); indentations.removeAt(indentations.size()-1); int loc = Locations.endOf(prevToken.location); push(new Token(SCLTerminals.RBRACE, loc, loc, "implicit }")); @@ -142,6 +152,13 @@ public class SCLPostLexer { } } firstTokenOfLine = false; + if(isFirstToken) { + isFirstToken = false; + if(symbol.id == SCLTerminals.ID && symbol.text.equals("module") && options != null && options.isModule) { + push(new Token(SCLTerminals.MODULE, symbol.location, symbol.text)); + return; + } + } } switch(symbolId) { @@ -149,36 +166,52 @@ public class SCLPostLexer { case SCLTerminals.LPAREN: case SCLTerminals.LBRACKET: case SCLTerminals.IF: + case SCLTerminals.WHEN: + case SCLTerminals.LET: indentations.add(-1); + indentationTokens.add(symbolId); push(symbol); return; + case SCLTerminals.THEN: + /*for(int tt : indentationTokens.toArray()) + System.out.print(SCLParser.TERMINAL_NAMES[tt] + " "); + System.out.println();*/ + if(prevTokenId == SCLTerminals.COMMA) { + // for list comprehension syntax + push(symbol); + break; + } case SCLTerminals.RBRACE: case SCLTerminals.RPAREN: case SCLTerminals.RBRACKET: case SCLTerminals.ELSE: case SCLTerminals.IN: - while(!indentations.isEmpty() && indentations.removeAt(indentations.size()-1) >= 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)