2011-07-04 3 views
2

나는 C++ 코드 기반으로 작업하고 있습니다. 지금은 전체 코드베이스를 살펴보고 프로그램에서 사용되는 모든 문자열 목록을 반환하는 루아 스크립트를 호출하는 C++ 코드를 사용하고 있습니다.코드베이스에서 하드 코딩 된 문자열을 추출하기위한 루아 패턴 일치

문제의 문자열 앞에 항상 TRANS라는 JUCE 매크로가 있습니다. 다음은 문자열

TRANS("Normal") 
TRANS ("With spaces") 
TRANS("") 
TRANS("multiple"" ""quotations") 
TRANS(")") 
TRANS("spans \ 
multiple \ 
lines") 

을 추출 할 몇 가지 예입니다 그리고 난 당신이 큰 코드베이스에서 발생할 수있는 몇 가지 다른 가능한 문자열 varients을 상상할 수있는 확신합니다. 가능한 한 많은 프로세스를 자동화하기 위해 JUCE 변환 형식의 파일을 생성하는 자동화 도구를 만들고 있습니다.

이 문자열을 찾기 위해 패턴 일치를 위해이 코드를 사용했습니다. 나는 루아 문자열

path = ... 

--Open file and read source into string 
file = io.open(path, "r") 
str = file:read("*all") 

로 소스 코드를 변환 TRANS로 시작하는 패턴을 발견

for word in string.gmatch(string, 'TRANS%s*%b()') do print(word) end 

라고 괄호를 균형했다했습니다. 이것은 나에게 괄호를 포함하여 전체 매크로를 얻을 것이다. 그러나 거기에서 나는 필요하지 않은 뚱뚱한 부분을 분리하고 실제 문자열 값을 유지하는 것이 꽤 쉬울 것이라고 생각했다.

그러나 괄호 불균형을 일으키는 문자열에는이 기능이 작동하지 않습니다. 예컨대 TRANS(")") 대신 내가

for word in string.gmatch(string, 'TRANS%s*(%s*%b""%s*') do print(word) end 

내 패턴을 수정 TRANS("(")

의, TRANS(") 리턴, 패턴은 TRANS 한 후, 0 또는 여러 공백으로 시작해야합니다. 그 다음에는 (문자 뒤에 0 개 이상의 공백이 있어야합니다.) 이제 대괄호 안에 들어가서 ""기호의 균형을 맞추고 뒤에 0 또는 여러 공백을 추가하고 마지막으로 a)로 끝내야합니다. 불행히도이 값을 사용하면 단일 값을 반환하지 않습니다. 하지만 ... 생각했던대로 작동한다고 생각합니다 ... 내부에 \"이있을 수 있습니다. 이로 인해 브래킷 불균형이 발생합니다.

이러한 문자열을 추출하는 방법에 대한 조언이 있으십니까? 패턴 매칭 시퀀스를 계속 찾아야 하나? 또는 직접 알고리즘을 시도해야합니다 ... 내 두 번째 패턴이 문자열을 반환하지 않는 이유를 알고 계십니까? 다른 조언! 나는 모든 가능성의 100 %를 감추려하고 있지는 않지만 100 %에 가깝다는 것은 굉장 할 것입니다. 감사! : D

답변

0

두 번째 경우, 괄호를 이스케이프하는 것을 잊었습니다. 내가 누구만큼 루아 패턴을 사랑하지만 당신이 총 싸움에 칼을 데려 와야

for word in string.gmatch(str, 'TRANS%s*%(%s*(%b"")%s*%)') do print(word) end 
+0

아, 나는 (마크에 대한 이스케이프 문자가 필요하다는 것을 몰랐다. 그리고 나는 당신의 대답이 내가 이전에 가지고있는 더 나은 형식의 문자열을주는 방식을 좋아한다 ... 불행히도 이것은 여전히 ​​TRANS ("\" ") 또는 그 안에 인용 부호가있는 임의의 문자열 ... –

+0

@ 콜톤, 루아 패턴으로 100 % 또는 그 근처에있을 수 있다고 생각하지 않습니다. C를 이해하는 실제 렉서가 필요합니다 문자열 규칙.C 전 처리기 ('cpp' 또는'gcc -E')를 사용하여 결과를 쉽게 후 처리 할 수있게 해주는'TRANS' 정의를 제안합니다. 나는'#define TRANS (x) BEGIN x END'를 사용하여 간단한 테스트를 수행했으며 예제에서는 잘 작동한다. – lhf

+0

나는 당신의 대답이 무엇을 의미하는지 정확히 모르겠습니다. 나는 C 전 처리기 매크로가 TRANS라는 것을 알고 있지만이 빠른 테스트 #define으로 무엇을 얻고 있는지 알지 못합니다. 더 자세히 설명해 주시겠습니까? :) –

1

을보십시오. 이것은 솔루션을 정규 표현식으로 코딩하고 싶지 않은 문제 중 하나입니다. 큰 따옴표와 백 슬래시 이스케이프를 올바르게 처리하려면 실제 파서가 필요하며 LPEG은 사용자의 필요를 잘 관리합니다.

+0

LPEG는 일반적인 루아 패턴에 비해 어떤 이점이 있습니까? 읽을 거리가 많습니다. 관심을 가질만한 특정 기능을 제공 할 수 있습니까? 또한 패턴이 충분하지 않을 것이라고 확신합니까? 내가 믿는 모든 경계 조건을 100 % 커버 할 필요는 없습니다 ... 제가 작업하고있는 툴의 사용에는 중요하지 않습니다. 지금은 하나의 패턴보다는 단계적으로 이것을 시도하는 것이 더 좋은 아이디어 일지 궁금합니다. –

+0

LPEG는 완전한 파서 시스템입니다. TRANS 매크로 인스턴스, 균형 괄호 및 균형 잡힌'''표시, 백 슬래시 이스케이프 및 암시 적 연결을 포함하는 C 문자열 리터럴의 전체 구문과 일치하는 문법을 작성할 수 있습니다. 그러면 LPEG에서 문법을 적용 할 수 있습니다. 원본 텍스트를 읽고 알아야 할 것을 꺼내십시오. 큰 패키지이지만 그만한 가치가 있습니다. LEX 및 YACC가 제공하는 모든 것을 제공하는 것과 같은 것으로 생각하십시오. – RBerteig