2016-09-20 4 views
1

나는 parathesis 사이의 텍스트를 세미콜론으로 끝내려고합니다. (. *)PEG.js (와) 사이에 텍스트를 가져옵니다.

예 : 나는이 시도했다 (in here there can be 'anything' !"#¤);); any character is possible);

Text 
= "(" text:(.*) ");" { return text.join(""); } 

그러나 보인다는) 마지막이 포함됩니다; 전에 ");" 않습니다. 오류가 발생합니다.

Expected ");" or any character but end of input found

문제는 텍스트에 ");" 그래서 나는 가장 바깥 쪽을 원해요.) 줄이 끝나면 내리십시오.

이 정규식 \((.*)\);은 내가 원하는 것을 수행하지만 PEG.js에서 어떻게 할 수 있습니까? 결과에 바깥 괄호와 세미콜론을 포함하고 싶지 않습니다.

+0

나는 있습니다. 내가 찾고있는 것을 찾지 못했습니다. 또는 어쩌면 나는 그것을 이해하지 않았다. 문서의 어느 부분이 지정되었는지 알고 있다면 어디에서 말해 줄 수 있는지 알려 주시면 감사하겠습니다. – mottosson

답변

5

당신이 무슨 일을하는지 알고 있다면 그것은 아주 쉽게해야처럼이 보인다 = P는 그래서, 요점은 정규식이 아닌 상태에서 PEG가 결정적이라는 것이다. 따라서 PEG는 일부 입력을 수용하면 되돌릴 수 없습니다. 그런 다음 원하는 의미를 시뮬레이션 할 수 있습니다. 정규식 \((.*)\);이 원하는대로 처리한다고 가정하기 때문에 이것을 PEG로 변환 할 수 있습니다.

이 정규식의 기능은 무엇입니까? 입력의 끝까지 모든 문자를 소비 한 다음 );을 찾을 때까지 역 추적을 유지합니다. 즉, 마지막으로 가능한 한 );을 소비합니다.

PEG와 함께 작동하려면 미리 );이 있으면 소비를 계속하기 위해 미리보기를 사용해야합니다.

따라서 용액은 :

Text 
= "(" text:TextUntilTerminator ");" { return text.join(""); } 

TextUntilTerminator 
= x:(&HaveTerminatorAhead .)* { return x.map(y => y[1]) } 

HaveTerminatorAhead 
= . (!");" .)* ");" 

TextUntilTerminator 비 단자를 소모하면서 소모없이 HaveTerminatorAhead일치 (룩어를 상기 & 기호). 그런 다음 하나의 단일 문자를 사용합니다. 입력시 최종 );에 도달했음을 알 때까지 그렇게합니다.

HaveTerminalAhead 비 터미널은 간단합니다. 한 문자 앞으로 있는지 확인하고, 그 뒤에 있으면 하나 이상의 문자가 );임을 확인합니다. 또한 부제 - 앞머리 !을 사용하여 처음으로 );에서 멈추도록합니다 (원래의 문제를 재현 할 것임).

이 PEG는 사용자가 제안한 정규식의 동작을 재현합니다.

+0

니스, 작동! 그리고 나도 몇 가지 것을 배웠습니다 =) 고마워요! – mottosson

+0

더 큰 문법에서 이것을 사용한다면 아마도 다른 종류의 미리보기를 추가하여 검사를 제한해야합니다. 위의 코드는 입력에 마지막');을 쓰고 싶다고 가정합니다.이 경우는'_beyond_ a''를'Text'와 일치시키려는 경우에는 원하는 동작이 아닐 수도 있습니다. – paulotorrens

+0

여러 줄의 파일을 읽을 것입니다.하지만 이것을 고려하기 위해 \ n을 문법에 추가 할 수 있을까요? – mottosson

관련 문제