From 189ed79c285a2032a17fb3833e17f6884c3f8d40 Mon Sep 17 00:00:00 2001 From: sblundy Date: Sun, 11 Aug 2019 06:23:58 -0700 Subject: [PATCH] Fix braced list properly --- .../sblundy/elvish/lang/ElvishParser.java | 14 +-- .../sblundy/elvish/psi/ElvishBraced.java | 4 +- .../sblundy/elvish/psi/ElvishTypes.java | 1 + .../elvish/psi/impl/ElvishBracedImpl.java | 8 +- src/main/grammars/Elvish.bnf | 5 +- .../github/sblundy/elvish/lang/parserUtils.kt | 97 ++----------------- .../elvish/lang/braced-list.tokens.txt | 15 +++ .../sblundy/elvish/lang/braced-list.txt | 19 ++-- 8 files changed, 47 insertions(+), 116 deletions(-) create mode 100644 src/test/resources/com/github/sblundy/elvish/lang/braced-list.tokens.txt diff --git a/src/gen/com/github/sblundy/elvish/lang/ElvishParser.java b/src/gen/com/github/sblundy/elvish/lang/ElvishParser.java index 32f3148..a9218bd 100644 --- a/src/gen/com/github/sblundy/elvish/lang/ElvishParser.java +++ b/src/gen/com/github/sblundy/elvish/lang/ElvishParser.java @@ -230,7 +230,7 @@ private static boolean Bareword_0(PsiBuilder builder_, int level_) { } /* ********************************************************** */ - // OPEN_BRACE (Space | EOL)* Compound (BracedSep* Compound)* (Space | EOL)* CLOSE_BRACE + // OPEN_BRACE (Space | EOL)* Bareword (BracedSep* Bareword)* (Space | EOL)* CLOSE_BRACE public static boolean Braced(PsiBuilder builder_, int level_) { if (!recursion_guard_(builder_, level_, "Braced")) return false; if (!nextTokenIs(builder_, OPEN_BRACE)) return false; @@ -238,7 +238,7 @@ public static boolean Braced(PsiBuilder builder_, int level_) { Marker marker_ = enter_section_(builder_); result_ = consumeToken(builder_, OPEN_BRACE); result_ = result_ && Braced_1(builder_, level_ + 1); - result_ = result_ && Compound(builder_, level_ + 1); + result_ = result_ && Bareword(builder_, level_ + 1); result_ = result_ && Braced_3(builder_, level_ + 1); result_ = result_ && Braced_4(builder_, level_ + 1); result_ = result_ && consumeToken(builder_, CLOSE_BRACE); @@ -266,7 +266,7 @@ private static boolean Braced_1_0(PsiBuilder builder_, int level_) { return result_; } - // (BracedSep* Compound)* + // (BracedSep* Bareword)* private static boolean Braced_3(PsiBuilder builder_, int level_) { if (!recursion_guard_(builder_, level_, "Braced_3")) return false; while (true) { @@ -277,13 +277,13 @@ private static boolean Braced_3(PsiBuilder builder_, int level_) { return true; } - // BracedSep* Compound + // BracedSep* Bareword private static boolean Braced_3_0(PsiBuilder builder_, int level_) { if (!recursion_guard_(builder_, level_, "Braced_3_0")) return false; boolean result_; Marker marker_ = enter_section_(builder_); result_ = Braced_3_0_0(builder_, level_ + 1); - result_ = result_ && Compound(builder_, level_ + 1); + result_ = result_ && Bareword(builder_, level_ + 1); exit_section_(builder_, marker_, null, result_); return result_; } @@ -320,13 +320,13 @@ private static boolean Braced_4_0(PsiBuilder builder_, int level_) { } /* ********************************************************** */ - // (Space | EOL)* ',' (Space | EOL)* + // (Space | EOL)* <> (Space | EOL)* public static boolean BracedSep(PsiBuilder builder_, int level_) { if (!recursion_guard_(builder_, level_, "BracedSep")) return false; boolean result_; Marker marker_ = enter_section_(builder_, level_, _NONE_, BRACED_SEP, ""); result_ = BracedSep_0(builder_, level_ + 1); - result_ = result_ && consumeToken(builder_, ","); + result_ = result_ && parseCommaAsSeparator(builder_, level_ + 1); result_ = result_ && BracedSep_2(builder_, level_ + 1); exit_section_(builder_, level_, marker_, result_, false, null); return result_; diff --git a/src/gen/com/github/sblundy/elvish/psi/ElvishBraced.java b/src/gen/com/github/sblundy/elvish/psi/ElvishBraced.java index ef857ba..2be1c8d 100644 --- a/src/gen/com/github/sblundy/elvish/psi/ElvishBraced.java +++ b/src/gen/com/github/sblundy/elvish/psi/ElvishBraced.java @@ -8,9 +8,9 @@ public interface ElvishBraced extends PsiElement { @NotNull - List getBracedSepList(); + List getBarewordList(); @NotNull - List getCompoundList(); + List getBracedSepList(); } diff --git a/src/gen/com/github/sblundy/elvish/psi/ElvishTypes.java b/src/gen/com/github/sblundy/elvish/psi/ElvishTypes.java index f340698..e5f8af2 100644 --- a/src/gen/com/github/sblundy/elvish/psi/ElvishTypes.java +++ b/src/gen/com/github/sblundy/elvish/psi/ElvishTypes.java @@ -51,6 +51,7 @@ public interface ElvishTypes { IElementType AMPERSAND = new ElvishTokenType("&"); IElementType AT_SYMBOL = new ElvishTokenType("@"); IElementType BAREWORD_CHAR = new ElvishTokenType("BAREWORD_CHAR"); + IElementType BRACED_SEPARATOR = new ElvishTokenType("[, ]+"); IElementType CLOSE_BRACE = new ElvishTokenType("}"); IElementType CLOSE_BRACKET = new ElvishTokenType("]"); IElementType CLOSE_PARAN = new ElvishTokenType(")"); diff --git a/src/gen/com/github/sblundy/elvish/psi/impl/ElvishBracedImpl.java b/src/gen/com/github/sblundy/elvish/psi/impl/ElvishBracedImpl.java index e3d6ba3..38de8ac 100644 --- a/src/gen/com/github/sblundy/elvish/psi/impl/ElvishBracedImpl.java +++ b/src/gen/com/github/sblundy/elvish/psi/impl/ElvishBracedImpl.java @@ -28,14 +28,14 @@ public void accept(@NotNull PsiElementVisitor visitor) { @Override @NotNull - public List getBracedSepList() { - return PsiTreeUtil.getChildrenOfTypeAsList(this, ElvishBracedSep.class); + public List getBarewordList() { + return PsiTreeUtil.getChildrenOfTypeAsList(this, ElvishBareword.class); } @Override @NotNull - public List getCompoundList() { - return PsiTreeUtil.getChildrenOfTypeAsList(this, ElvishCompound.class); + public List getBracedSepList() { + return PsiTreeUtil.getChildrenOfTypeAsList(this, ElvishBracedSep.class); } } diff --git a/src/main/grammars/Elvish.bnf b/src/main/grammars/Elvish.bnf index c0c43df..a7e1015 100644 --- a/src/main/grammars/Elvish.bnf +++ b/src/main/grammars/Elvish.bnf @@ -43,6 +43,7 @@ BAREWORD_CHAR="regexp:[./@%+!]" VARIABLE_CHAR="regexp:[0-9a-zA-Z\-_:~]" COMMAND_BAREWORD_CHAR="regexp:[<>*^]" + BRACED_SEPARATOR="[, ]+" WILDCARD="*" KEYWORD_ELSE="else" KEYWORD_ELIF="elif" @@ -113,8 +114,8 @@ OutputCapture ::= OPEN_PARAN Chunk CLOSE_PARAN Lambda ::= LambdaArguments? OPEN_BRACE Chunk CLOSE_BRACE LambdaArguments ::=OPEN_BRACKET Space? ((parameter | MapPair) Space?)* CLOSE_BRACKET parameter ::= AT_SYMBOL? Compound -Braced ::= OPEN_BRACE (Space | EOL)* Compound (BracedSep* Compound)* (Space | EOL)* CLOSE_BRACE -BracedSep ::= (Space | EOL)* ',' (Space | EOL)* +Braced ::= OPEN_BRACE (Space | EOL)* Bareword (BracedSep* Bareword)* (Space | EOL)* CLOSE_BRACE +BracedSep ::= (Space | EOL)* <> (Space | EOL)* // Special Commands diff --git a/src/main/kotlin/com/github/sblundy/elvish/lang/parserUtils.kt b/src/main/kotlin/com/github/sblundy/elvish/lang/parserUtils.kt index 947d000..0afe1bd 100644 --- a/src/main/kotlin/com/github/sblundy/elvish/lang/parserUtils.kt +++ b/src/main/kotlin/com/github/sblundy/elvish/lang/parserUtils.kt @@ -2,12 +2,8 @@ package com.github.sblundy.elvish.lang -import com.github.sblundy.elvish.ElvishBundle import com.github.sblundy.elvish.psi.ElvishTypes -import com.github.sblundy.elvish.psi.ElvishTypes.CONTINUATION import com.intellij.lang.PsiBuilder -import com.intellij.lang.parser.GeneratedParserUtilBase -import com.intellij.psi.tree.TokenSet private val keywords = setOf( ElvishTypes.KEYWORD_DEL, @@ -21,94 +17,15 @@ private val keywords = setOf( ElvishTypes.KEYWORD_TRY, ElvishTypes.KEYWORD_WHILE) -fun parseKeywordAsBareword(builder: PsiBuilder, level: Int): Boolean { - if (!(builder.tokenType in keywords)) return false - builder.remapCurrentToken(ElvishTypes.BAREWORD_CHAR) - return true -} - -fun parseArgList( - builder: PsiBuilder, - level: Int, - arg: GeneratedParserUtilBase.Parser, - lineTerminator: GeneratedParserUtilBase.Parser -): Boolean { - if (!GeneratedParserUtilBase.recursion_guard_(builder, level, "parseArgList")) return false - while (true) { - val pos_ = GeneratedParserUtilBase.current_position_(builder) - GeneratedParserUtilBase.consumeToken(builder, CONTINUATION) - val result = lineTerminator.parse(builder, level) - if (result) return true - val marker = builder.mark() - if (!arg.parse(builder, level)) { - marker.drop() - break - } else if (builder.trailingWhitespaceContainsEOL(builder.currentOffset)) { - marker.rollbackTo() - builder.remap(builder.whiteSpaceRange()) - arg.parse(builder, level) - lineTerminator.parse(builder, level) - break - } - marker.drop() - if (!GeneratedParserUtilBase.empty_element_parsed_guard_(builder, "parseArgList", pos_)) break - } +fun parseCommaAsSeparator(builder: PsiBuilder, level: Int): Boolean { + if (builder.tokenText != ",") return false + builder.remapCurrentToken(ElvishTypes.BRACED_SEPARATOR) + builder.advanceLexer() return true } -fun parseBlockBody( - builder: PsiBuilder, - level: Int, - command: GeneratedParserUtilBase.Parser -): Boolean { - if (!GeneratedParserUtilBase.recursion_guard_(builder, level, "parseBlockBody")) return false - while (true) { - val pos_ = GeneratedParserUtilBase.current_position_(builder) - if (!command.parse(builder, level)) { - if (builder.tokenType == ElvishTypes.CLOSE_BRACE) { - break - } - - val marker = builder.mark() - skipCountingBraces(builder, TokenSet.create(ElvishTypes.CLOSE_BRACE)) - marker.error(ElvishBundle.message("psi.error.command")) - } - if (!GeneratedParserUtilBase.empty_element_parsed_guard_(builder, "parseBlockBody", pos_)) break - } +fun parseKeywordAsBareword(builder: PsiBuilder, level: Int): Boolean { + if (!(builder.tokenType in keywords)) return false + builder.remapCurrentToken(ElvishTypes.BAREWORD_CHAR) return true -} - -fun parseCompoundExpressionSegment(builder: PsiBuilder, - level: Int, - parser: GeneratedParserUtilBase.Parser, - following: GeneratedParserUtilBase.Parser): Boolean { - if (!GeneratedParserUtilBase.recursion_guard_(builder, level, "parseCompoundExpressionSegment")) return false - val marker_ = GeneratedParserUtilBase.enter_section_(builder) - var result: Boolean = parser.parse(builder, level) && !builder.hasTrailingWhitespace() - if (result) { - result = following.parse(builder, level) - } - - GeneratedParserUtilBase.exit_section_(builder, marker_, null, result) - return result -} - -private fun skipCountingBraces(builder: PsiBuilder, until: TokenSet): Boolean { - var braceLevel = 0 - while (true) { - if (builder.eof()) { - return false - } - val type = builder.tokenType - if (braceLevel == 0 && until.contains(type)) { - return true - } - - if (ElvishTypes.OPEN_BRACE === type) { - braceLevel++ - } else if (ElvishTypes.CLOSE_BRACE === type) { - braceLevel-- - } - builder.advanceLexer() - } } \ No newline at end of file diff --git a/src/test/resources/com/github/sblundy/elvish/lang/braced-list.tokens.txt b/src/test/resources/com/github/sblundy/elvish/lang/braced-list.tokens.txt new file mode 100644 index 0000000..06260a2 --- /dev/null +++ b/src/test/resources/com/github/sblundy/elvish/lang/braced-list.tokens.txt @@ -0,0 +1,15 @@ +ElvishTokenType.VARIABLE_CHAR ('ls') +ElvishTokenType.INLINE_WHITESPACE (' ') +ElvishTokenType.VARIABLE_CHAR ('01') +ElvishTokenType.BAREWORD_CHAR ('/') +ElvishTokenType.{ ('{') +ElvishTokenType.VARIABLE_CHAR ('03') +BAD_CHARACTER (',') +ElvishTokenType.VARIABLE_CHAR ('10') +BAD_CHARACTER (',') +ElvishTokenType.VARIABLE_CHAR ('17') +ElvishTokenType.} ('}') +ElvishTokenType.BAREWORD_CHAR ('/') +ElvishTokenType.VARIABLE_CHAR ('2000-logs') +ElvishTokenType.BAREWORD_CHAR ('.') +ElvishTokenType.VARIABLE_CHAR ('txt') \ No newline at end of file diff --git a/src/test/resources/com/github/sblundy/elvish/lang/braced-list.txt b/src/test/resources/com/github/sblundy/elvish/lang/braced-list.txt index 8c3e67a..5ab8286 100644 --- a/src/test/resources/com/github/sblundy/elvish/lang/braced-list.txt +++ b/src/test/resources/com/github/sblundy/elvish/lang/braced-list.txt @@ -11,19 +11,16 @@ Elvish File PsiElement(ElvishTokenType.BAREWORD_CHAR)('/') ElvishBracedImpl(BRACED) PsiElement(ElvishTokenType.{)('{') - ElvishCompoundImpl(COMPOUND) - ElvishBarewordImpl(BAREWORD) - PsiElement(ElvishTokenType.VARIABLE_CHAR)('03') + ElvishBarewordImpl(BAREWORD) + PsiElement(ElvishTokenType.VARIABLE_CHAR)('03') ElvishBracedSepImpl(BRACED_SEP) - PsiElement(BAD_CHARACTER)(',') - ElvishCompoundImpl(COMPOUND) - ElvishBarewordImpl(BAREWORD) - PsiElement(ElvishTokenType.VARIABLE_CHAR)('10') + PsiElement(ElvishTokenType.[, ]+)(',') + ElvishBarewordImpl(BAREWORD) + PsiElement(ElvishTokenType.VARIABLE_CHAR)('10') ElvishBracedSepImpl(BRACED_SEP) - PsiElement(BAD_CHARACTER)(',') - ElvishCompoundImpl(COMPOUND) - ElvishBarewordImpl(BAREWORD) - PsiElement(ElvishTokenType.VARIABLE_CHAR)('17') + PsiElement(ElvishTokenType.[, ]+)(',') + ElvishBarewordImpl(BAREWORD) + PsiElement(ElvishTokenType.VARIABLE_CHAR)('17') PsiElement(ElvishTokenType.})('}') ElvishBarewordImpl(BAREWORD) PsiElement(ElvishTokenType.BAREWORD_CHAR)('/')