From 8d466b160ef39b7f62552517d66bcd83bbbb2c16 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Fri, 5 Feb 2021 19:13:09 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E9=83=A8=E5=88=86?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=EF=BC=8C=E8=BF=98=E9=9C=80=E8=A6=81=E8=BF=9B?= =?UTF-8?q?=E8=A1=8C=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sum/spirit/core/AliasReplacer.java | 8 +- .../spirit/core/element/action/CoreLexer.java | 45 +++--- .../core/element/action/SemanticParser.java | 8 +- .../element/lexer/AbstractLexerAction.java | 50 +++---- .../core/element/lexer/BorderAction.java | 38 +++++ .../core/element/lexer/LexerContext.java | 11 +- .../spirit/core/element/lexer/LexerEvent.java | 2 +- .../sum/spirit/core/element/lexer/Region.java | 34 +++++ .../core/element/lexer/RegionAction.java | 135 +++++++++++------- .../core/element/lexer/SymbolAction.java | 8 +- .../java/com/sum/spirit/utils/LineUtils.java | 18 +-- .../com/sum/spirit/utils/SpringUtils.java | 6 +- .../java/com/sum/test/inner/InnerInvoker.java | 11 -- .../java/com/sum/test/type/GenericType.java | 6 +- .../src/test/java/com/sum/test/type/Type.java | 6 +- 15 files changed, 247 insertions(+), 139 deletions(-) create mode 100644 spirit-core/src/main/java/com/sum/spirit/core/element/lexer/BorderAction.java create mode 100644 spirit-core/src/main/java/com/sum/spirit/core/element/lexer/Region.java delete mode 100644 spirit-test/src/test/java/com/sum/test/inner/InnerInvoker.java diff --git a/spirit-core/src/main/java/com/sum/spirit/core/AliasReplacer.java b/spirit-core/src/main/java/com/sum/spirit/core/AliasReplacer.java index bcbd576a..8e75c709 100644 --- a/spirit-core/src/main/java/com/sum/spirit/core/AliasReplacer.java +++ b/spirit-core/src/main/java/com/sum/spirit/core/AliasReplacer.java @@ -22,7 +22,7 @@ public class AliasReplacer { public String replace(String code, String alias, String className) { StringBuilder builder = new StringBuilder(code); AliasLexer lexer = new AliasLexer(alias, className); - lexer.replace(builder); + lexer.process(new LexerContext(builder), lexer); return builder.toString(); } @@ -40,10 +40,10 @@ public class AliasReplacer { public boolean isTrigger(LexerEvent event) { LexerContext context = event.context; StringBuilder builder = context.builder; - char char0 = event.char0; - if (char0 == '"') { + char ch = event.ch; + if (ch == '"') { context.index = LineUtils.findEndIndex(builder, context.index, '"', '"'); - } else if (char0 == alias.charAt(0) && !LineUtils.isLetter(builder.charAt(context.index - 1))) { + } else if (ch == alias.charAt(0) && !LineUtils.isLetter(builder.charAt(context.index - 1))) { return true; } return false; diff --git a/spirit-core/src/main/java/com/sum/spirit/core/element/action/CoreLexer.java b/spirit-core/src/main/java/com/sum/spirit/core/element/action/CoreLexer.java index e0169410..17c3958b 100644 --- a/spirit-core/src/main/java/com/sum/spirit/core/element/action/CoreLexer.java +++ b/spirit-core/src/main/java/com/sum/spirit/core/element/action/CoreLexer.java @@ -8,11 +8,13 @@ import java.util.regex.Pattern; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.DependsOn; import org.springframework.stereotype.Component; import com.sum.spirit.api.LexerAction; import com.sum.spirit.core.element.lexer.AbstractLexerAction; +import com.sum.spirit.core.element.lexer.BorderAction; import com.sum.spirit.core.element.lexer.LexerContext; import com.sum.spirit.core.element.lexer.LexerEvent; import com.sum.spirit.utils.LineUtils; @@ -26,51 +28,62 @@ public class CoreLexer extends AbstractLexerAction implements InitializingBean { public List actions; + @Autowired + public BorderAction borderAction; + @Override public void afterPropertiesSet() throws Exception { - actions = SpringUtils.getBeansAndSort(LexerAction.class, CoreLexer.class);// 排除自己 + actions = SpringUtils.getBeansAndSort(LexerAction.class, CoreLexer.class, BorderAction.class);// 排除自己 } - public List getWords(String text, Character... ignoreOnceChars) { + public List getWords(String text) { // 拆分方法体时,会传入空的text if (StringUtils.isEmpty(text)) { return new ArrayList<>(); } - StringBuilder builder = new StringBuilder(text.trim()); + // 上下文 + LexerContext context = new LexerContext(new StringBuilder(text.trim())); // 触发事件 - Map replacedStrs = replace(builder, ignoreOnceChars); + process(context, this); // 去掉多余的空格 - text = LineUtils.mergeSpaces(builder.toString()); + text = LineUtils.mergeSpaces(context.builder.toString()); // 利用空格,进行拆分 List words = new ArrayList<>(Arrays.asList(text.split(" "))); // 继续拆分单词 splitWords(words); // 还原被替换的单词 - restoreWords(words, replacedStrs); + restoreWords(words, context.replacedStrs); return words; } - public Map replace(StringBuilder builder, Character... ignoreOnceChars) { - // 生成上下文 - LexerContext context = new LexerContext(builder, new ArrayList<>(Arrays.asList(ignoreOnceChars))); + public List getSubWords(String text, Character... splitChars) { + // 上下文 + LexerContext context = new LexerContext(new StringBuilder(text.trim()), splitChars); + // 触发事件 + process(context, borderAction); + + return null; + } + + public void process(LexerContext context, LexerAction action) { + StringBuilder builder = context.builder; for (; context.index < builder.length(); context.index++) { - char currChar = builder.charAt(context.index); + char ch = builder.charAt(context.index); // 是否连续字符 - if ((context.startIndex < 0 && isContinuous(currChar)) || isRefreshed(currChar)) { + if ((context.startIndex < 0 && isContinuous(ch)) || isRefreshed(ch)) { context.startIndex = context.index; } // 这里使用统一的逻辑处理 - LexerEvent event = new LexerEvent(context, currChar); - if (isTrigger(event)) { - pushStack(event); + LexerEvent event = new LexerEvent(context, ch); + if (action.isTrigger(event)) { + action.pushStack(event); } // 如果不是连续字符,则重置游标 - if (!isContinuous(currChar)) { + if (!isContinuous(ch)) { context.startIndex = -1; } } - return context.replacedStrs; } public void splitWords(List words) { diff --git a/spirit-core/src/main/java/com/sum/spirit/core/element/action/SemanticParser.java b/spirit-core/src/main/java/com/sum/spirit/core/element/action/SemanticParser.java index 3fb20ffe..356b7ce2 100644 --- a/spirit-core/src/main/java/com/sum/spirit/core/element/action/SemanticParser.java +++ b/spirit-core/src/main/java/com/sum/spirit/core/element/action/SemanticParser.java @@ -61,7 +61,11 @@ public class SemanticParser extends AbstractSemanticParser { } else if (isAccess(word)) { token.tokenType = getAccessTokenType(word); } - Assert.notNull(token.tokenType, "Token type cannot be null!"); + try { + Assert.notNull(token.tokenType, "Token type cannot be null!"); + } catch (Exception e) { + System.out.println(""); + } } public void setTokenValue(String word, Token token) { @@ -83,7 +87,7 @@ public class SemanticParser extends AbstractSemanticParser { return word; } // 如果是类型,则直接用尖括号进行拆分,如果是其他,则不使用尖括号进行拆分 - List words = insideType ? lexer.getWords(word, '<') : lexer.getWords(word, '(', '[', '{'); + List words = insideType ? lexer.getSubWords(word, '<', '>') : lexer.getSubWords(word, '(', ')', '[', ']', '{', '}'); String first = words.get(0); List tokens = null; // 如果第一个单词是一个前缀的话,则添加前缀 diff --git a/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/AbstractLexerAction.java b/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/AbstractLexerAction.java index bee0bb8f..1f10fba0 100644 --- a/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/AbstractLexerAction.java +++ b/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/AbstractLexerAction.java @@ -7,44 +7,38 @@ import com.sum.spirit.utils.LineUtils; public abstract class AbstractLexerAction implements LexerAction { - public void pushStack(StringBuilder builder, int start, char left, char right, String markName, Map replacedStrs) { - int end = LineUtils.findEndIndex(builder, start, left, right); - replaceStr(builder, start, end + 1, markName, replacedStrs); + public Region findRegion(StringBuilder builder, int fromIndex, char leftChar, char rightChar) { + int endIndex = LineUtils.findEndIndex(builder, fromIndex, leftChar, rightChar); + return endIndex != -1 ? new Region(fromIndex, endIndex + 1) : null; } - public void pushStack(StringBuilder builder, int start, char left, char right, char left1, char right1, String markName, Map replacedStrs) { - int finalEnd = LineUtils.findEndIndex(builder, start, left, right); - if (finalEnd != -1 && finalEnd + 1 < builder.length()) { - char c = builder.charAt(finalEnd + 1); - if (c == ' ' && finalEnd + 2 < builder.length()) {// 允许中间有个空格 - char d = builder.charAt(finalEnd + 2); - if (d == left1) { - int secondEnd = LineUtils.findEndIndex(builder, finalEnd + 2, left1, right1); - if (secondEnd != -1) { - finalEnd = secondEnd; - } - } - } else { - if (c == left1) { - int secondEnd = LineUtils.findEndIndex(builder, finalEnd + 1, left1, right1); - if (secondEnd != -1) { - finalEnd = secondEnd; - } - } + public Region mergeRegions(Region... regions) { + Region finalRegion = new Region(-1, -1); + for (Region region : regions) { + if (region == null) { + continue; + } + if (finalRegion.startIndex == -1 || region.startIndex < finalRegion.startIndex) { + finalRegion.startIndex = region.startIndex; + } + if (finalRegion.endIndex == -1 || region.endIndex > finalRegion.endIndex) { + finalRegion.endIndex = region.endIndex; } } - replaceStr(builder, start, finalEnd + 1, markName, replacedStrs); + return finalRegion; } - public void replaceStr(StringBuilder builder, int start, int end, String markName, Map replacedStrs) { - if (end == -1) { - return; + public int replaceStr(StringBuilder builder, Region region, String markName, Map replacedStrs) { + if (region == null) { + return 0; } - String content = builder.substring(start, end); + String content = builder.substring(region.startIndex, region.endIndex); if (replacedStrs != null) { replacedStrs.put(markName, content); } - builder.replace(start, end, " " + markName + " "); + markName = " " + markName + " "; + builder.replace(region.startIndex, region.endIndex, markName); + return markName.length() - region.size(); } } diff --git a/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/BorderAction.java b/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/BorderAction.java new file mode 100644 index 00000000..f28f6193 --- /dev/null +++ b/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/BorderAction.java @@ -0,0 +1,38 @@ +package com.sum.spirit.core.element.lexer; + +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +@Component +@Order(-100) +public class BorderAction extends RegionAction { + +// @Override +// public boolean isTrigger(LexerEvent event) { +// return event.context.splitChars.contains(event.ch) && super.isTrigger(event); +// } +// +// @Override +// public void doPushStack(LexerEvent event, List regions, String markName) { +// LexerContext context = event.context; +// StringBuilder builder = context.builder; +// int shift = 0; +// for (Region region : regions) { +// if (region == null) { +// continue; +// } +// if (context.splitChars.contains(builder.charAt(region.shift(shift).startIndex))) { +// int lastShift = replaceStr(builder, region.getStartBorder(), "@separator" + context.nameCount++, context.replacedStrs); +// shift += lastShift; +// shift += replaceStr(builder, region.getEndBorder().shift(lastShift), "@separator" + context.nameCount++, context.replacedStrs); +// } +// } +// context.splitChars.clear(); +// } +// +// @Override +// public void resetIndex(LexerEvent event) { +// // ignore +// } + +} diff --git a/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/LexerContext.java b/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/LexerContext.java index 8c6c521c..09b7c2b7 100644 --- a/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/LexerContext.java +++ b/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/LexerContext.java @@ -1,5 +1,6 @@ package com.sum.spirit.core.element.lexer; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -15,18 +16,18 @@ import lombok.NonNull; public class LexerContext { public StringBuilder builder; - public List ignoreChars; + public List splitChars; public int nameCount; @NonNull public Map replacedStrs = new HashMap<>(); - public int index; public int startIndex = -1; - public int endIndex = -1; + public int index; - public LexerContext(StringBuilder builder, List ignoreChars) { + public LexerContext(StringBuilder builder, Character... splitChars) { this.builder = builder; - this.ignoreChars = ignoreChars; + this.splitChars = Arrays.asList(splitChars); } + } diff --git a/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/LexerEvent.java b/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/LexerEvent.java index 6762fc60..6f39209e 100644 --- a/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/LexerEvent.java +++ b/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/LexerEvent.java @@ -11,5 +11,5 @@ import lombok.NoArgsConstructor; @AllArgsConstructor public class LexerEvent { public LexerContext context; - public char char0; + public char ch; } diff --git a/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/Region.java b/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/Region.java new file mode 100644 index 00000000..da49cc75 --- /dev/null +++ b/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/Region.java @@ -0,0 +1,34 @@ +package com.sum.spirit.core.element.lexer; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class Region { + + public int startIndex; + public int endIndex; + + public Region getStartBorder() { + return new Region(startIndex, startIndex + 1); + } + + public Region getEndBorder() { + return new Region(endIndex - 1, endIndex); + } + + public int size() { + return endIndex - startIndex; + } + + public Region shift(int shift) { + startIndex += shift; + endIndex += shift; + return this; + } +} diff --git a/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/RegionAction.java b/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/RegionAction.java index bc137e89..0680d5f5 100644 --- a/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/RegionAction.java +++ b/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/RegionAction.java @@ -1,13 +1,12 @@ package com.sum.spirit.core.element.lexer; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; -import java.util.Map; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; -import com.sum.spirit.utils.LineUtils; - @Component @Order(-100) public class RegionAction extends AbstractLexerAction { @@ -17,16 +16,7 @@ public class RegionAction extends AbstractLexerAction { LexerContext context = event.context; StringBuilder builder = context.builder; - List ignoreChars = context.ignoreChars; - char char0 = event.char0; - - // 是否忽略该字符 - if (ignoreChars.contains(char0) && context.index > context.endIndex) { - context.startIndex = -1; - context.endIndex = LineUtils.findEndIndex(builder, context.index, char0, LineUtils.flipChar(char0)); - ignoreChars.remove(new Character(char0)); - return false; - } + char ch = event.ch; // 是否已经到达结尾 if (context.index == builder.length() - 1) { @@ -34,10 +24,10 @@ public class RegionAction extends AbstractLexerAction { } // 如果是以下字符,则进行弹栈 - if (char0 == '"' || char0 == '\'' || char0 == '{' || char0 == '(' || char0 == '[') { + if (ch == '"' || ch == '\'' || ch == '{' || ch == '(' || ch == '[') { return true; - } else if (char0 == '<') {// 一般泛型声明都是以大写字母开头的 + } else if (ch == '<') {// 一般泛型声明都是以大写字母开头的 if (context.startIndex >= 0) { char d = builder.charAt(context.startIndex); if (d >= 'A' && d <= 'Z') { @@ -52,47 +42,88 @@ public class RegionAction extends AbstractLexerAction { @Override public void pushStack(LexerEvent event) { + char ch = event.ch; + + List regions = getRegions(event); + if (ch == '"') { + doPushStack(event, regions, "@str"); + + } else if (ch == '\'') { + doPushStack(event, regions, "@char"); + + } else if (ch == '{') { + doPushStack(event, regions, "@map"); + + } else if (ch == '(') { + doPushStack(event, regions, "@invoke_like"); + resetIndex(event); + + } else if (ch == '[') { + doPushStack(event, regions, "@array_like"); + resetIndex(event); + + } else if (ch == '<') { + doPushStack(event, regions, "@generic"); + resetIndex(event); + } + } + + public List getRegions(LexerEvent event) { + LexerContext context = event.context; StringBuilder builder = context.builder; - List ignoreChars = context.ignoreChars; - Map replacedStrs = context.replacedStrs; - char char0 = event.char0; - - if (char0 == '"') { - pushStack(builder, context.index, '"', '"', "@str" + context.nameCount++, replacedStrs); - - } else if (char0 == '\'') { - pushStack(builder, context.index, '\'', '\'', "@char" + context.nameCount++, replacedStrs); - - } else if (char0 == '{') { - pushStack(builder, context.index, '{', '}', "@map" + context.nameCount++, replacedStrs); - - } else if (char0 == '(') { - int idx = context.startIndex >= 0 ? context.startIndex : context.index; - pushStack(builder, idx, '(', ')', "@invoke_like" + context.nameCount++, replacedStrs); - context.index = idx; - - } else if (char0 == '[') { - if (ignoreChars.contains('{') && context.index > context.endIndex) {// 一般来说,Java中没有泛型数组的声明方式 - int idx = context.startIndex >= 0 ? context.startIndex : context.index; - pushStack(builder, idx, '[', ']', "@array_like" + context.nameCount++, replacedStrs); - context.index = idx; - - } else { - int idx = context.startIndex >= 0 ? context.startIndex : context.index; - pushStack(builder, idx, '[', ']', '{', '}', "@array_like" + context.nameCount++, replacedStrs); - context.index = idx; + char ch = event.ch; + + if (ch == '"') { + Region region = findRegion(builder, context.index, '"', '"'); + return Arrays.asList(region); + + } else if (ch == '\'') { + Region region = findRegion(builder, context.index, '\'', '\''); + return Arrays.asList(region); + + } else if (ch == '{') { + Region region = findRegion(builder, context.index, '{', '}'); + return Arrays.asList(region); + + } else if (ch == '(') { + Region region0 = context.startIndex >= 0 ? new Region(context.startIndex, context.index) : null; + Region region1 = findRegion(builder, context.index, '(', ')'); + return Arrays.asList(region0, region1); + + } else if (ch == '[') { + Region region0 = context.startIndex >= 0 ? new Region(context.startIndex, context.index) : null; + Region region1 = findRegion(builder, context.index, '[', ']'); + Region region2 = null; + if (region1.endIndex < builder.length() && builder.charAt(region1.endIndex) == '{') { + region2 = findRegion(builder, region1.endIndex, '{', '}'); + + } else if (region1.endIndex + 1 < builder.length() && builder.charAt(region1.endIndex) == ' ' && builder.charAt(region1.endIndex + 1) == '{') { + region2 = findRegion(builder, region1.endIndex + 1, '{', '}'); } - - } else if (char0 == '<') { - if (ignoreChars.contains('(') && context.index > context.endIndex) { - pushStack(builder, context.startIndex, '<', '>', "@generic" + context.nameCount++, replacedStrs); - context.index = context.startIndex; - - } else { - pushStack(builder, context.startIndex, '<', '>', '(', ')', "@generic" + context.nameCount++, replacedStrs); - context.index = context.startIndex; + return Arrays.asList(region0, region1, region2); + + } else if (ch == '<') { + Region region0 = context.startIndex >= 0 ? new Region(context.startIndex, context.index) : null; + Region region1 = findRegion(builder, context.index, '<', '>'); + Region region2 = null; + if (region1.endIndex < builder.length() && builder.charAt(region1.endIndex) == '(') { + region2 = findRegion(builder, region1.endIndex, '(', ')'); } + return Arrays.asList(region0, region1, region2); } + + return new ArrayList<>(); } + + public void doPushStack(LexerEvent event, List regions, String markName) { + LexerContext context = event.context; + replaceStr(context.builder, mergeRegions((Region[]) regions.toArray()), markName + context.nameCount++, context.replacedStrs); + } + + public void resetIndex(LexerEvent event) { + LexerContext context = event.context; + context.index = context.startIndex >= 0 ? context.startIndex : context.index; + } + } diff --git a/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/SymbolAction.java b/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/SymbolAction.java index 39d6b3b3..3bba125b 100644 --- a/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/SymbolAction.java +++ b/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/SymbolAction.java @@ -13,7 +13,7 @@ public class SymbolAction extends AbstractLexerAction { @Override public boolean isTrigger(LexerEvent event) { - return SymbolEnum.isSymbolChar(event.char0); + return SymbolEnum.isSymbolChar(event.ch); } @Override @@ -27,7 +27,8 @@ public class SymbolAction extends AbstractLexerAction { if (context.index + 1 < builder.length()) { String str = builder.substring(context.index, context.index + 2); if (SymbolEnum.isDoubleSymbol(str)) { - replaceStr(builder, context.index, context.index + 2, "@symbol" + context.nameCount++, replacedStrs); + Region region = new Region(context.index, context.index + 2); + replaceStr(builder, region, "@symbol" + context.nameCount++, replacedStrs); return; } } @@ -35,7 +36,8 @@ public class SymbolAction extends AbstractLexerAction { // 尝试获取一个字符,判断是否双字符符号 String str = builder.substring(context.index, context.index + 1); if (SymbolEnum.isSingleSymbol(str)) { - replaceStr(builder, context.index, context.index + 1, "@symbol" + context.nameCount++, replacedStrs); + Region region = new Region(context.index, context.index + 1); + replaceStr(builder, region, "@symbol" + context.nameCount++, replacedStrs); return; } diff --git a/spirit-core/src/main/java/com/sum/spirit/utils/LineUtils.java b/spirit-core/src/main/java/com/sum/spirit/utils/LineUtils.java index aebf98a6..f99d5046 100644 --- a/spirit-core/src/main/java/com/sum/spirit/utils/LineUtils.java +++ b/spirit-core/src/main/java/com/sum/spirit/utils/LineUtils.java @@ -53,33 +53,33 @@ public class LineUtils { return count % 2 == 0; } - public static int findEndIndex(CharSequence chars, int start, char left, char right) { + public static int findEndIndex(CharSequence chars, int fromIndex, char leftChar, char rightChar) { boolean flag = false; - for (int index = start, count = 0; index < chars.length(); index++) { - char c = chars.charAt(index); - if (c == '"' && isNotEscaped(chars, index)) {// 如果是“"”符号,并且没有被转义 + for (int index = fromIndex, count = 0; index < chars.length(); index++) { + char ch = chars.charAt(index); + if (ch == '"' && isNotEscaped(chars, index)) {// 如果是“"”符号,并且没有被转义 flag = !flag; - if (!flag && right == '"') { + if (!flag && rightChar == '"') { return index; } } if (!flag) { if (count % 2 == 0) {// 防止完全一样的分隔符|xxx| - if (c == left) { + if (ch == leftChar) { count++; - } else if (c == right) { + } else if (ch == rightChar) { count--; if (count == 0) { return index; } } } else { - if (c == right) { + if (ch == rightChar) { count--; if (count == 0) { return index; } - } else if (c == left) { + } else if (ch == leftChar) { count++; } } diff --git a/spirit-core/src/main/java/com/sum/spirit/utils/SpringUtils.java b/spirit-core/src/main/java/com/sum/spirit/utils/SpringUtils.java index 6f9974d7..0ef84f2e 100644 --- a/spirit-core/src/main/java/com/sum/spirit/utils/SpringUtils.java +++ b/spirit-core/src/main/java/com/sum/spirit/utils/SpringUtils.java @@ -1,6 +1,7 @@ package com.sum.spirit.utils; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -40,9 +41,10 @@ public class SpringUtils implements ApplicationContextAware { return beans; } - public static List getBeansAndSort(Class type, Class excludedType) { + public static List getBeansAndSort(Class type, Class... excludedTypes) { List beans = getBeansAndSort(type); - return beans.stream().filter((t) -> t.getClass() != excludedType).collect(Collectors.toList()); + List> list = Arrays.asList(excludedTypes); + return beans.stream().filter((t) -> !list.contains(t)).collect(Collectors.toList()); } public static List getBeansAndSort(Class type, String scanPackage) { diff --git a/spirit-test/src/test/java/com/sum/test/inner/InnerInvoker.java b/spirit-test/src/test/java/com/sum/test/inner/InnerInvoker.java deleted file mode 100644 index 1ef3edf6..00000000 --- a/spirit-test/src/test/java/com/sum/test/inner/InnerInvoker.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.sum.test.inner; - -public class InnerInvoker { - - public Inner inner = new Inner(); - - public int testInner() { - return inner.getAge(); - } - -} diff --git a/spirit-test/src/test/java/com/sum/test/type/GenericType.java b/spirit-test/src/test/java/com/sum/test/type/GenericType.java index b78158f3..c301f990 100644 --- a/spirit-test/src/test/java/com/sum/test/type/GenericType.java +++ b/spirit-test/src/test/java/com/sum/test/type/GenericType.java @@ -14,16 +14,16 @@ public class GenericType extends HashMap { } public HashMap test() { - return new HashMap(); + return new HashMap(); } public Integer test1() { - GenericType g = new GenericType(); + GenericType g = new GenericType(); return g.get("test"); } public HashMap test2() { - GenericType g = new GenericType(); + GenericType g = new GenericType(); return g.test(); } diff --git a/spirit-test/src/test/java/com/sum/test/type/Type.java b/spirit-test/src/test/java/com/sum/test/type/Type.java index ec0e7a75..fed70d1b 100644 --- a/spirit-test/src/test/java/com/sum/test/type/Type.java +++ b/spirit-test/src/test/java/com/sum/test/type/Type.java @@ -62,7 +62,7 @@ public class Type { logger.info("test class {}", clz); Type self = this; logger.info("test this {}", self); - HashMap hmap = new HashMap(); + HashMap hmap = new HashMap(); hmap.put("key", "value"); long long1 = 100L; logger.info("long1 is ", long1); @@ -81,7 +81,7 @@ public class Type { logger.info("" + ssss); String xxss = testParam(null, null); logger.info(xxss); - ServiceImpl service = new ServiceImpl(); + ServiceImpl service = new ServiceImpl(); String type = service.testReturnGenericType("text"); logger.info(type.toString()); String key = service.key; @@ -90,7 +90,7 @@ public class Type { logger.info("" + serNum); String serStr = service.test1("hello"); logger.info("" + serStr); - GenericType generic = new GenericType(); + GenericType generic = new GenericType(); Integer gKey = generic.get("test"); logger.info(gKey + ""); List intsss = Lists.newArrayList(1, 123, 8987879); -- Gitee From dcc00a387a4bb0ea58bcccc1301a3ef9188634c0 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Sun, 7 Feb 2021 20:06:15 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E9=87=8D=E6=9E=84=E8=AF=8D=E6=B3=95?= =?UTF-8?q?=E5=88=86=E6=9E=90=E5=99=A8=EF=BC=8C=E5=B9=B6=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=89=80=E6=9C=89bug,=E5=90=8E=E7=BB=AD=E4=BC=9A=E5=86=8D?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spirit/core/element/action/CoreLexer.java | 19 +++-- .../core/element/action/SemanticParser.java | 7 +- .../element/lexer/AbstractLexerAction.java | 3 + .../core/element/lexer/BorderAction.java | 75 ++++++++++++------- .../core/element/lexer/LexerContext.java | 2 + .../sum/spirit/core/element/lexer/Region.java | 13 ---- .../core/element/lexer/RegionAction.java | 48 +++--------- .../core/element/lexer/SymbolAction.java | 2 +- .../com/sum/spirit/utils/SpringUtils.java | 2 +- .../java/com/sum/test/type/GenericType.java | 6 +- .../src/test/java/com/sum/test/type/Type.java | 6 +- 11 files changed, 87 insertions(+), 96 deletions(-) diff --git a/spirit-core/src/main/java/com/sum/spirit/core/element/action/CoreLexer.java b/spirit-core/src/main/java/com/sum/spirit/core/element/action/CoreLexer.java index 17c3958b..40eb67d2 100644 --- a/spirit-core/src/main/java/com/sum/spirit/core/element/action/CoreLexer.java +++ b/spirit-core/src/main/java/com/sum/spirit/core/element/action/CoreLexer.java @@ -26,11 +26,11 @@ public class CoreLexer extends AbstractLexerAction implements InitializingBean { public static final Pattern TYPE_END_PATTERN = Pattern.compile("^[\\s\\S]+\\.[A-Z]+\\w+$"); - public List actions; - @Autowired public BorderAction borderAction; + public List actions; + @Override public void afterPropertiesSet() throws Exception { actions = SpringUtils.getBeansAndSort(LexerAction.class, CoreLexer.class, BorderAction.class);// 排除自己 @@ -57,18 +57,27 @@ public class CoreLexer extends AbstractLexerAction implements InitializingBean { return words; } + @SuppressWarnings("unchecked") public List getSubWords(String text, Character... splitChars) { // 上下文 LexerContext context = new LexerContext(new StringBuilder(text.trim()), splitChars); // 触发事件 process(context, borderAction); - return null; + List finalWords = new ArrayList<>(); + List subWords = (List) context.attachments.get(BorderAction.SUB_WORDS); + if (subWords == null || subWords.isEmpty()) { + throw new RuntimeException("Word split failed!"); + } + for (String subWord : subWords) { + finalWords.addAll(getWords(subWord)); + } + return finalWords; } public void process(LexerContext context, LexerAction action) { - StringBuilder builder = context.builder; - for (; context.index < builder.length(); context.index++) { + // 开始遍历 + for (StringBuilder builder = context.builder; context.index < builder.length(); context.index++) { char ch = builder.charAt(context.index); // 是否连续字符 if ((context.startIndex < 0 && isContinuous(ch)) || isRefreshed(ch)) { diff --git a/spirit-core/src/main/java/com/sum/spirit/core/element/action/SemanticParser.java b/spirit-core/src/main/java/com/sum/spirit/core/element/action/SemanticParser.java index 356b7ce2..9ec9951f 100644 --- a/spirit-core/src/main/java/com/sum/spirit/core/element/action/SemanticParser.java +++ b/spirit-core/src/main/java/com/sum/spirit/core/element/action/SemanticParser.java @@ -61,11 +61,8 @@ public class SemanticParser extends AbstractSemanticParser { } else if (isAccess(word)) { token.tokenType = getAccessTokenType(word); } - try { - Assert.notNull(token.tokenType, "Token type cannot be null!"); - } catch (Exception e) { - System.out.println(""); - } + + Assert.notNull(token.tokenType, "Token type cannot be null!"); } public void setTokenValue(String word, Token token) { diff --git a/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/AbstractLexerAction.java b/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/AbstractLexerAction.java index 1f10fba0..4ea2f844 100644 --- a/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/AbstractLexerAction.java +++ b/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/AbstractLexerAction.java @@ -5,6 +5,8 @@ import java.util.Map; import com.sum.spirit.api.LexerAction; import com.sum.spirit.utils.LineUtils; +import cn.hutool.core.lang.Assert; + public abstract class AbstractLexerAction implements LexerAction { public Region findRegion(StringBuilder builder, int fromIndex, char leftChar, char rightChar) { @@ -25,6 +27,7 @@ public abstract class AbstractLexerAction implements LexerAction { finalRegion.endIndex = region.endIndex; } } + Assert.isTrue(finalRegion.startIndex != -1 && finalRegion.endIndex != -1, "An exception occurred in the merge regions!"); return finalRegion; } diff --git a/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/BorderAction.java b/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/BorderAction.java index f28f6193..7b61402d 100644 --- a/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/BorderAction.java +++ b/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/BorderAction.java @@ -1,5 +1,10 @@ package com.sum.spirit.core.element.lexer; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -7,32 +12,48 @@ import org.springframework.stereotype.Component; @Order(-100) public class BorderAction extends RegionAction { -// @Override -// public boolean isTrigger(LexerEvent event) { -// return event.context.splitChars.contains(event.ch) && super.isTrigger(event); -// } -// -// @Override -// public void doPushStack(LexerEvent event, List regions, String markName) { -// LexerContext context = event.context; -// StringBuilder builder = context.builder; -// int shift = 0; -// for (Region region : regions) { -// if (region == null) { -// continue; -// } -// if (context.splitChars.contains(builder.charAt(region.shift(shift).startIndex))) { -// int lastShift = replaceStr(builder, region.getStartBorder(), "@separator" + context.nameCount++, context.replacedStrs); -// shift += lastShift; -// shift += replaceStr(builder, region.getEndBorder().shift(lastShift), "@separator" + context.nameCount++, context.replacedStrs); -// } -// } -// context.splitChars.clear(); -// } -// -// @Override -// public void resetIndex(LexerEvent event) { -// // ignore -// } + public static final String SUB_WORDS = "SUB_WORDS"; + + @Override + public void doPushStack(LexerEvent event, List regions, String markName) { + LexerContext context = event.context; + StringBuilder builder = context.builder; + List splitChars = context.splitChars; + Map attachments = context.attachments; + List subWords = new ArrayList<>(); + Region prefixRegion = null; + for (Region region : regions) { + if (region == null) { + continue; + } + char startChar = builder.charAt(region.startIndex); + char endChar = builder.charAt(region.endIndex - 1); + if (splitChars.contains(startChar) && splitChars.contains(endChar)) { + subWords.add(builder.substring(region.startIndex, region.startIndex + 1)); + if (region.endIndex - 1 > region.startIndex + 1) { + String content = builder.substring(region.startIndex + 1, region.endIndex - 1); + if (StringUtils.isNotBlank(content)) { + subWords.add(content); + } + } + subWords.add(builder.substring(region.endIndex - 1, region.endIndex)); + } else { + prefixRegion = mergeRegions(prefixRegion, region); + } + } + // 在头部插入前缀 + if (prefixRegion != null) { + subWords.add(0, builder.substring(prefixRegion.startIndex, prefixRegion.endIndex)); + } + // 添加到上下文参数中 + attachments.put(SUB_WORDS, subWords); + // 重置索引到结束位置 + context.index = builder.length(); + } + + @Override + public void resetIndex(LexerEvent event) { + // ignore + } } diff --git a/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/LexerContext.java b/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/LexerContext.java index 09b7c2b7..c735db12 100644 --- a/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/LexerContext.java +++ b/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/LexerContext.java @@ -25,6 +25,8 @@ public class LexerContext { public int startIndex = -1; public int index; + public Map attachments = new HashMap<>(); + public LexerContext(StringBuilder builder, Character... splitChars) { this.builder = builder; this.splitChars = Arrays.asList(splitChars); diff --git a/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/Region.java b/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/Region.java index da49cc75..1a88544b 100644 --- a/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/Region.java +++ b/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/Region.java @@ -14,21 +14,8 @@ public class Region { public int startIndex; public int endIndex; - public Region getStartBorder() { - return new Region(startIndex, startIndex + 1); - } - - public Region getEndBorder() { - return new Region(endIndex - 1, endIndex); - } - public int size() { return endIndex - startIndex; } - public Region shift(int shift) { - startIndex += shift; - endIndex += shift; - return this; - } } diff --git a/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/RegionAction.java b/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/RegionAction.java index 0680d5f5..59ae8858 100644 --- a/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/RegionAction.java +++ b/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/RegionAction.java @@ -1,6 +1,5 @@ package com.sum.spirit.core.element.lexer; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -8,7 +7,7 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @Component -@Order(-100) +@Order(-80) public class RegionAction extends AbstractLexerAction { @Override @@ -42,54 +41,27 @@ public class RegionAction extends AbstractLexerAction { @Override public void pushStack(LexerEvent event) { - char ch = event.ch; - - List regions = getRegions(event); - if (ch == '"') { - doPushStack(event, regions, "@str"); - - } else if (ch == '\'') { - doPushStack(event, regions, "@char"); - - } else if (ch == '{') { - doPushStack(event, regions, "@map"); - - } else if (ch == '(') { - doPushStack(event, regions, "@invoke_like"); - resetIndex(event); - - } else if (ch == '[') { - doPushStack(event, regions, "@array_like"); - resetIndex(event); - - } else if (ch == '<') { - doPushStack(event, regions, "@generic"); - resetIndex(event); - } - } - - public List getRegions(LexerEvent event) { - LexerContext context = event.context; StringBuilder builder = context.builder; char ch = event.ch; if (ch == '"') { Region region = findRegion(builder, context.index, '"', '"'); - return Arrays.asList(region); + doPushStack(event, Arrays.asList(region), "@str"); } else if (ch == '\'') { Region region = findRegion(builder, context.index, '\'', '\''); - return Arrays.asList(region); + doPushStack(event, Arrays.asList(region), "@char"); } else if (ch == '{') { Region region = findRegion(builder, context.index, '{', '}'); - return Arrays.asList(region); + doPushStack(event, Arrays.asList(region), "@map"); } else if (ch == '(') { Region region0 = context.startIndex >= 0 ? new Region(context.startIndex, context.index) : null; Region region1 = findRegion(builder, context.index, '(', ')'); - return Arrays.asList(region0, region1); + doPushStack(event, Arrays.asList(region0, region1), "@invoke_like"); + resetIndex(event); } else if (ch == '[') { Region region0 = context.startIndex >= 0 ? new Region(context.startIndex, context.index) : null; @@ -101,7 +73,8 @@ public class RegionAction extends AbstractLexerAction { } else if (region1.endIndex + 1 < builder.length() && builder.charAt(region1.endIndex) == ' ' && builder.charAt(region1.endIndex + 1) == '{') { region2 = findRegion(builder, region1.endIndex + 1, '{', '}'); } - return Arrays.asList(region0, region1, region2); + doPushStack(event, Arrays.asList(region0, region1, region2), "@array_like"); + resetIndex(event); } else if (ch == '<') { Region region0 = context.startIndex >= 0 ? new Region(context.startIndex, context.index) : null; @@ -110,10 +83,9 @@ public class RegionAction extends AbstractLexerAction { if (region1.endIndex < builder.length() && builder.charAt(region1.endIndex) == '(') { region2 = findRegion(builder, region1.endIndex, '(', ')'); } - return Arrays.asList(region0, region1, region2); + doPushStack(event, Arrays.asList(region0, region1, region2), "@generic"); + resetIndex(event); } - - return new ArrayList<>(); } public void doPushStack(LexerEvent event, List regions, String markName) { diff --git a/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/SymbolAction.java b/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/SymbolAction.java index 3bba125b..3c5fd4ec 100644 --- a/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/SymbolAction.java +++ b/spirit-core/src/main/java/com/sum/spirit/core/element/lexer/SymbolAction.java @@ -8,7 +8,7 @@ import org.springframework.stereotype.Component; import com.sum.spirit.core.common.enums.SymbolEnum; @Component -@Order(-80) +@Order(-60) public class SymbolAction extends AbstractLexerAction { @Override diff --git a/spirit-core/src/main/java/com/sum/spirit/utils/SpringUtils.java b/spirit-core/src/main/java/com/sum/spirit/utils/SpringUtils.java index 0ef84f2e..7c98a186 100644 --- a/spirit-core/src/main/java/com/sum/spirit/utils/SpringUtils.java +++ b/spirit-core/src/main/java/com/sum/spirit/utils/SpringUtils.java @@ -44,7 +44,7 @@ public class SpringUtils implements ApplicationContextAware { public static List getBeansAndSort(Class type, Class... excludedTypes) { List beans = getBeansAndSort(type); List> list = Arrays.asList(excludedTypes); - return beans.stream().filter((t) -> !list.contains(t)).collect(Collectors.toList()); + return beans.stream().filter((t) -> !list.contains(t.getClass())).collect(Collectors.toList()); } public static List getBeansAndSort(Class type, String scanPackage) { diff --git a/spirit-test/src/test/java/com/sum/test/type/GenericType.java b/spirit-test/src/test/java/com/sum/test/type/GenericType.java index c301f990..b78158f3 100644 --- a/spirit-test/src/test/java/com/sum/test/type/GenericType.java +++ b/spirit-test/src/test/java/com/sum/test/type/GenericType.java @@ -14,16 +14,16 @@ public class GenericType extends HashMap { } public HashMap test() { - return new HashMap(); + return new HashMap(); } public Integer test1() { - GenericType g = new GenericType(); + GenericType g = new GenericType(); return g.get("test"); } public HashMap test2() { - GenericType g = new GenericType(); + GenericType g = new GenericType(); return g.test(); } diff --git a/spirit-test/src/test/java/com/sum/test/type/Type.java b/spirit-test/src/test/java/com/sum/test/type/Type.java index fed70d1b..ec0e7a75 100644 --- a/spirit-test/src/test/java/com/sum/test/type/Type.java +++ b/spirit-test/src/test/java/com/sum/test/type/Type.java @@ -62,7 +62,7 @@ public class Type { logger.info("test class {}", clz); Type self = this; logger.info("test this {}", self); - HashMap hmap = new HashMap(); + HashMap hmap = new HashMap(); hmap.put("key", "value"); long long1 = 100L; logger.info("long1 is ", long1); @@ -81,7 +81,7 @@ public class Type { logger.info("" + ssss); String xxss = testParam(null, null); logger.info(xxss); - ServiceImpl service = new ServiceImpl(); + ServiceImpl service = new ServiceImpl(); String type = service.testReturnGenericType("text"); logger.info(type.toString()); String key = service.key; @@ -90,7 +90,7 @@ public class Type { logger.info("" + serNum); String serStr = service.test1("hello"); logger.info("" + serStr); - GenericType generic = new GenericType(); + GenericType generic = new GenericType(); Integer gKey = generic.get("test"); logger.info(gKey + ""); List intsss = Lists.newArrayList(1, 123, 8987879); -- Gitee