2017-03-25 7 views
1

나는 현재 행복 언어 & Alex를 사용하여 장난감 언어 의 컴파일러에 대한 파서를 작성하고 있습니다. 선택적 레이아웃의 일부 형식이 필요하기 때문에 비 -과 일치하기 전에 Alex의 상태를 변경해야합니다. 불행히도 해피가 요구하는 미리보기 토큰은 전에 읽은 것 같습니다 알렉스의 상태를 변경할 수있는 기회가 있습니다. 이 문제에 대한 일반적인 접근 방식은해피 앤드렉스 - 파서 - 렉서 통신에 영향을주는 룩어 헤드 방지하기

funcDef : header localDefs block 
         ^I have to change alex's state 
          before the underlying lexer 
          starts reading the block tokens. 

있습니까 : 여기

작은 조각은 문제를 시연?

+0

블록 시작 위치를 어떻게 알 수 있습니까? 나는'localDefs'가 self-terminating이 아니라고 생각합니다. 그래서 블록이 어디에서 시작 하는지를 알기 위해 사용할 수있는 어휘 기능이 있어야합니다. 당신은 아마 조금 설명 할 수 있을까요? – rici

+0

@rici 블록은 begin/end 키워드로 둘러싸여 있거나 그렇지 않으면 들여 쓰기 기반입니다. 기본적으로 begin stmts + end 또는 stmts autoend로 정의됩니다. 식별자 변경을 감지하면 자동 시작을 생성하기 위해 시작자가 누락되었다는 것을 렉서에게 알릴 필요가 있습니다. 전체적인 접근법은 더 좋은 방법이되어야한다는 것을 매우 해로운 것으로 느낍니다. –

+0

2 주 전에이 _exact_ 문제를 방금 해결했습니다. 다른 사람이 그걸 가로 질러 달릴 것이라고 생각하지 않았습니다. – Alec

답변

0

당신이 스레드 레 렉서를 사용하고 있다고 가정합니다. (해피와 알렉스가 같은 모나드에서 실행 중입니다.) 비슷한 문제에 직면했을 때 사용한 트릭은 빈 프로덕션 규칙을 만들어 규칙에 적용하는 것입니다.

changeAlexState :: {() } 
    : {- empty -} {%% \tok -> changeAlexState *> pushTok tok } 

funcDef : header localDefs changeAlexState block 

그런 다음, 당신은 (P이 렉싱/분석 모나드 임) pushTok :: Token -> P()를 지원하도록 모나드에 몇 가지 상태를 추가하고 렉싱 때 때 항상 토큰을 팝업 확인해야합니다. %%documented here입니다.

n : t_1 ... t_n {%% <expr> }

는 ... <expr>의 유형 [ Token -> P a 정지]와 동일하지만,이 경우 룩어 토큰 실제로 폐기하고 새로운 토큰은 입력으로부터 판독된다. 이것은 다음 토큰을 변경하고 파싱을 계속하려는 경우에 유용 할 수 있습니다.

나는 오래 전에 비슷한 것을했다. Here is my "empty" rule, here is an example use of it, here is where my pushing function is definedhere is where I "pop" tokens. 어떻게 진행되는지 알려주세요!