我正在尝试创建一个执行以下操作的函数:
假设输入的代码是“(a 1 2 (b 3 4 5 (c 6) |7) 8 9)”,其中管道 | 符号是光标的位置,
函数返回:一个字符串“b 3 4 5 (c 6) 7”,表示光标范围内的代码
一个 int 8 表示字符串相对于输入的起始索引
一个 int 30 表示字符串相对于输入的结束索引
我已经有可以完全返回的工作代码。然而,问题在于忽略注释,同时跟踪上下文(例如字符串文字、我自己的文字分隔符等)。
这是跟踪上下文的代码:
public static void applyContext(Context context, String s, String snext, String sprev) {
if (s.equals("\"")) {
if (context.context == Context.Contexts.MAIN) {
context.context = Context.Contexts.STRING;
context.stringDelimiterIsADoubleQuote = true;
} else if (context.context == Context.Contexts.STRING && context.stringDelimiterIsADoubleQuote && !sprev.equals("\\"))
context.context = Context.Contexts.MAIN;
} else if (s.equals("\'")) {
if (context.context == Context.Contexts.MAIN) {
context.context = Context.Contexts.STRING;
context.stringDelimiterIsADoubleQuote = false;
} else if (context.context == Context.Contexts.STRING && !context.stringDelimiterIsADoubleQuote && !sprev.equals("\""))
context.context = Context.Contexts.MAIN;
} else if (s.equals("/") && snext.equals("/")) {
if (context.context == Context.Contexts.MAIN)
context.context = Context.Contexts.COMMENT;
} else if (s.equals("\n")) {
if(context.context == Context.Contexts.COMMENT)
context.context = Context.Contexts.MAIN;
}
else if (s.equals("\\")) {
if(context.context == Context.Contexts.MAIN)
context.context = Context.Contexts.PATTERN;
else if(context.context == Context.Contexts.PATTERN)
context.context = Context.Contexts.MAIN;
}
}
首先,我将像这样使用上面的函数:
String sampleCode = "(a b "cdef" g \c4 bb2 eb4 g4v0.75\)";
Context c = new Context(Context.Contexts.MAIN);
for(int i = 0; i < sampleCode.length(); i++) {
String s = String.valueOf(sampleCode.charAt(i));
String snext = *nullcheck* ? String.valueOf(sampleCode.charAt(i + 1)) : "";
String sprev = *nullcheck* ? String.valueOf(sampleCode.charAt(i - 1)) : "";
applyContext(c, s, snext, sprev);
if(c.context == blahlbah) doBlah();
}
其次,我将向前和向后使用它,因为当前执行描述顶部所述功能的方法是(在伪代码中):
function returnCodeInScopeOfCursor(theWholeCode::String, cursorIndex::int) {
var depthOfCodeAtCursorPosition::int = getDepth(theWholeCode, cursorIndex);
Context c = new Context(getContextAt(theWholeCode, cursorIndex));
var currDepth::int = depthOfCodeAtCursorPosition;
var startIndex::int, endIndex::int;
for(i = cursorIndex; i >= 0; i--) {//going backwards
s = .....
snext = ......
sprev = ......
applyContext(c, s, snext, sprev);
if(c.context == Context.MAIN) {
if s = "(" then currDepth --;
if s = ")" then currDepth ++;
}
when currDepth < depthOfCodeAtCursorPosition
startIndex = i + 1;
break;
}
currDepth = depthOfCodeAtCursorPosition;//reset
for(i = cursorIndex; i < theWholeCode.length; i++) {//going forwards
s = ...
snex......
sprev.....
applyContext(c, s, snext, sprev);
if(c.context == Context.MAIN) {
if s = "(" then currDepth ++;
if s = ")" then currDepth --;
}
when currDepth < depthOfCodeAtCursorPosition
endIndex = i - 1;
break;
}
var returnedStr = theWholeCode->from startIndex->to endIndex
return new IndexedCode(returnedStr, startIndex, endIndex);
如您所见,此功能可以正向和反向工作。或者至少是大部分。唯一的问题是,如果我向后使用此功能,正确扫描评论(由标准 ECMA 双斜杠“//”表示)会变得混乱。
如果我要为反向上下文应用程序创建一个单独的函数并递归检查每一行是否有双斜杠,然后将“//”之后的所有内容都设为注释(或在函数使用的方向上,在此之前的所有内容//),这将花费太多的处理时间,因为我想将其用作音乐的实时编码环境。
此外,在尝试执行该returnCodeInScopeOfCursor
方法之前删除注释可能不可行......因为我需要跟踪代码的索引以及不跟踪的内容。如果我要删除评论,所有代码位置都会变得一团糟,并跟踪我在哪里删除了确切的内容以及删除了多少字符等......我正在使用的文本区域输入 GUI(RichTextFX ) 不支持 Line-Char 跟踪,因此仅使用 char 索引跟踪所有内容,因此存在问题...
所以......我对如何处理我当前的代码感到非常困惑。任何帮助、建议、意见等......将不胜感激。