다음을 수행하는 함수를 만들려고합니다.
코드 입력이 "(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 이중 슬래시 "//"로 표시)이 문제가된다는 것입니다.
역방향 컨텍스트 응용 프로그램을위한 별도의 함수를 만들고 모든 줄에서 이중 슬래시를 재귀 적으로 확인한 다음 해당 '//'뒤의 모든 항목을 COMMENT (또는 함수 사용 방향, 그 이전의 모든 항목 //) 로 만듭니다 . 음악을위한 라이브 코딩 환경으로 사용하고 싶기 때문에 처리 시간이 너무 많이 걸립니다.
또한, 그 returnCodeInScopeOfCursor
방법을 시도하기 전에 주석을 제거하는 것은 불가능할 수 있습니다. 코드의 인덱스와 그렇지 않은 것들을 추적해야하기 때문입니다. 주석을 제거하면 모든 코드 위치가 엉망이되며 정확히 무엇을 제거했는지, 문자 수 등을 정확히 제거했는지 추적 할 수 있습니다. 작업중인 텍스트 영역 입력 GUI (RichTextFX )는 Line-Char 추적을 지원하지 않으므로 모든 것이 char 인덱스를 사용하여 추적되므로 문제가 있습니다.
그래서 ... 나는 현재 코드로 무엇을해야할지 완전히 당황합니다. 모든 도움, 제안, 조언 등을 대단히 감사하겠습니다.
당신이 의견을 사전에 변환 할 수 // This is a comment<CR>
에 { This is a comment}<CR>
당신이 다음 뒤로 걸을 수있는 언어가 와 앞으로.
이 변환을 안으로 적용하고 나가는 동안 되 돌리면 모든 것이 잘 될 것입니다. 우리가 교체주의 //...
와 {...}
모든 charaqcter 오프셋이 유지되도록.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다