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=3d3b7b2f512033d90e13119b8edbfa8960cbaafd;hp=866fb8c985c4126b6e368746b83c767953c66cda;hb=a8758de5bc19e5adb3f618d3038743a164f09912;hpb=12d9af17384d960b75d58c3935d2b7b46d93e87b 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..3d3b7b2f5 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,15 +31,17 @@ 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); NO_SEMICOLON_BEFORE.add(SCLTerminals.THEN); - NO_SEMICOLON_BEFORE.add(SCLTerminals.ELSE); NO_SEMICOLON_BEFORE.add(SCLTerminals.IN); 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,6 +51,7 @@ 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; @@ -56,6 +59,7 @@ public class SCLPostLexer { { indentations.add(0); + indentationTokens.add(SCLTerminals.EOF); } public SCLPostLexer(SCLLexer lexer) { @@ -125,6 +129,7 @@ public class SCLPostLexer { int symbolIndentation = symbolStart-lineStart; //System.out.println("symbolIndentation = " + symbolIndentation); indentations.add(symbolIndentation); + indentationTokens.add(prevTokenId); firstTokenOfLine = false; } else if(firstTokenOfLine) { @@ -135,11 +140,12 @@ 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 }")); } - if(indentations.get(indentations.size()-1) == level) + if(indentations.get(indentations.size()-1) == level && symbolId != SCLTerminals.ELSE) push(new Token(SCLTerminals.SEMICOLON, symbolStart, symbolStart, "implicit ;")); } } @@ -151,37 +157,48 @@ 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.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 }")); + 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 && removedToken == SCLTerminals.WHEN) + curToken = symbol = new Token(SCLTerminals.THEN_AFTER_WHEN, symbol.location, 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 }")); - } - if(indentations.isEmpty()) - throw error(symbolStart, symbolEnd, "No corresponding opening parenthesis for '" + symbol.text + "'."); - push(symbol); - indentations.add(-1); + //if(symbolId == SCLTerminals.THEN) + // 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)