2009-05-08 6 views
1

저는 현재 렉서와 파서의 작동 방식을 배우고 있으며, 상태 시스템에 대한 다음 질문을 가지고 있습니다. 이 규칙 간단한 상태 전이 테이블의 경우 는 다음과 같이 표시됩니다 :구문 색 지정을위한 상태 시스템

current event next action 
IDLE $  COLOR - 
COLOR any -  OnColor() 
COLOR \n IDLE - 

이 '$'사이에있는 모든 문자 OnColor() 액션을 호출합니다 예를 들어, 나는 다음과 같은 규칙에 의해 텍스트 색상 화 필요 라인 끝 그래서 그것을 색칠 수 있습니다. 물론 같은 regexp에서 자동으로 생성 될 수 있지만, 정말 무거운 마술 사용하기 전에 어떻게 작동하는지 알고 싶다 :). 다음 문제는 간다 : 나는 규칙이있는 경우 : 가 (달러로 끝나는 텍스트의 라인 색상을 원하는을, 상태 전이 테이블은 매우 명확하지 않습니다 :

current  event next    action 
IDLE   any -    - 
IDLE   $  DOUND_DOLLAR  - 
FOUND_DOLLAR \n IDLE    OnDollar() 
FOUND_DOLLAR any IDLE    - 

나는 (OnDollar 전화를 내 상태 머신을 가르 칠 수) 줄 끝에 '$'기호가있는 경우 달러 기호가 나타나기 전의 텍스트를 색칠하기 위해 할 수있는 일은 무엇입니까? 그런 문제를 해결하기위한 일반적인 패턴은 무엇입니까? 물론 regexp에는 1 줄이 있지만, 하지만 저는 정말로 그러한 파서가 상태 머신을 통해 어떻게 구현 될 수 있는지 알고 싶습니다. 전혀 불가능합니다.

답변

0

"Purple Dragon Book"(sic)을 읽으면 현대의 컴파일러와 해석자가 "look ahead"버퍼를 적극적으로 사용하고 최근 텍스트를 축적 한 것으로 보이므로 정확한 다음 기호와 몇 개의 이전 기호를 쉽게 확인할 수 있습니다 어휘 유형.

내 예제에서 event()는 누적 될 수있는 어휘의 유형을 결정하기 위해 다음 기호와 이전 기호를 볼 필요가 있습니다.

1

한 번에 한 문자 씩 색을 지정해야하는 경우 (즉, 버퍼링, 미리보기, 다시 그리기 또는 마블 카바비), 그것은 불가능합니다.

그렇지 않으면 이러한 기능을 사용할 수 있습니다. 기술은 사용 가능한 것에 달려 있습니다.

  • Recoloring - n 문자를 다시 칠하는 작업이 있습니다. 분명히 이것은 사소한 해결책입니다.

  • 버퍼링/마킹 - 버퍼 끝으로 문자를 배치하거나 문자를 통과시키는 대신 소스의 명명 된 표시를 설정하는 동작이 있습니다. 그런 다음 나중에 수행 할 작업을 찾을 때 버퍼를 커밋하거나 명명 된 표시에서 플러시하는 작업을 수행하십시오. 이것으로 1 문자 이상을 다시 칠하는 것은 다소 복잡해집니다.

  • Lookahead - 추측 전환이 있습니다. 즉 DFA 대신 NFA을 사용합니다.

+0

나는 전혀 제약이 없으며 실제 단어로 그러한 작업을 해결하는 '올바른'방법을 알고 싶다. 당연히 나는 추가 플래그/다중 상태로 임시 버퍼 및 팅커를 만들 수 있지만, 어떻게 든 이것이 과도기 테이블 상태 머신의 간단한 디자인에서 빠져 나간다고 느낍니다. ( – grigoryvp

+0

"아이의 지옥"- 농담이 아닙니다. 어떤 버퍼링이나 일부 미리보기가없는 경우 색칠을 시작하는 문자 앞에 문자를 색칠하는 것은 불가능합니다. –

+0

아마 어휘를 처음으로 스캔하는 것이 현명 할 것입니다. 그리고 토큰을 분석 할 때, 어휘선 텍스트를 분석 할뿐만 아니라 서로를 위치 시키십시오. 아니면 전환 테이블 상태 머신이 데이터를 더 스마트하게 축적 할 수 있도록하는 잘 알려진 트릭입니까? :) – grigoryvp

0

대부분의 색상 표시기는 항상 전체 라인 (대부분의 경우 충분 함)과 여러 줄 주석에 대한 "누출"플래그를 더한 큰 블록에서 작동합니다. 그러한 API에 대한 예제는 Qt Syntax Highlighter을 참조하십시오.

+0

Qt 구문 형광펜은 높은 수준의 일종 인 표준 정규식 문법을 사용합니다 :). 나는 regexp 마법을 통해 자동으로 생성하기 전에 올바른 상태 머신을 만드는 방법을 배우는 데 관심이 있습니다. – grigoryvp

+0

사실이지만 API의 전체 레이아웃, 필요한 데이터 및 입력을 잘라내는 방법은 많은 아이디어를 제공해야합니다. 문제. 근원을 사용하십시오, 루크! –