2016-10-30 3 views
1

내가 렉싱하고있는 언어는 런타임 구성에 따라 키워드를 핫 스왑 할 수 있어야합니다.ANTLR4 동적 토큰 유형

그것은 너무 오래 당신이 당신의 문법 (자바)에서 확인 매입 대상 특정 코드이기 때문에이 작업을 수행하는 방법을 상대적으로 간단합니다 그러나 1

lexer grammar LanguageLexer; 

tokens { 
If, Else, While // etc 
} 

@header { 
import java.util.Map; 
} 

@members { 
private Map<String, Integer> keywords; 
public NafiLexer(CharStream input, Map<String, Integer> keywords) { 
    this(input); 
    this.keywords = keywords; 
} 
} 

WS: [ \n\t\r]+ -> skip; 
ID: [a-zA-Z]+ { if(keywords.containsKey(getText())) setType(keywords.get(getText())); }; 

, 나는 제거하고자하는 모든 대상 별 내 .g4 파일의 코드입니다. .g4은 여러 프로젝트 언어로 여러 타겟 언어에서 사용됩니다.

Parser에서 Listener을 사용하여 포함 된 동작을 제거하고 문법을 응용 프로그램 별 코드에서 분리 할 수 ​​있습니다. 그러나, 렉서 레벨 에서이 작업을 수행 할 수있는 방법이있는 경우 아직 찾지 못했습니다 (따라서이 질문을 묻습니다).

이것을 달성하는 방법은 Lexer에서 가져온 TokenStream을 감싸는 것 같습니다. 이 포장은 TokenStream으로 제공된대로 Token을 읽고 현재 포함 된 조치의 변형을 현재있는 ID 토큰에 적용합니다.

이것은 이론상으로 구현하기 어렵지 않습니다. 그러나 이것은 이미 정의 된 ANTLR 기호로 가능해야하는 기능처럼 느껴집니다. 따라서, 질문 : 은 기존 ANTLR 시스템 내에서 TokenStream을 통과하는 토큰 유형을 조건부로 변경할 수 있습니까? 그렇지 않다면, 그 작업을 완수하는 가장 마찰적 인 방법은 무엇입니까? Java 라이브러리를 사용하는 예제가 가장 익숙합니다. 가장 익숙한 예제입니다.

그리고 하위 질문으로 : 내 목표 대상에 TokenTransformationStream을 작성하게되면 기존 라이브러리에 추가하는 것이 좋습니다. (I는 현재의 모든 제공된 대상에 대한 심볼을 만들 수 있습니다.) 당신이 정기적으로 생성자와 렉서를 구성하는 경우


1 예,이 충돌합니다. 실제 응용 프로그램에서는이 문제를 해결할 가치가 있지만이 예제에서는 중요하지 않습니다.

저는 이것이 몇 가지 이유로 렉서 레벨에서 적절한 작업이라고 생각합니다. 주된 이유는 키워드 토큰을 항상 키워드 토큰으로 전달한 다음 필요한 경우 파서 수준에서 상황 별 키워드와 같은 식별자로 사용할 수있게하는 것입니다. 또한, 단지 을 묻는 다른 질문이 효과를 얻으려면은 위의 제공되는 동작 방법과 기본적으로 동일한 방법을 제안합니다.

+0

입니다 .v4.runtime.TokenStreamRewriter'하지만 javadoc을 올바르게 읽는다면 텍스트 표현을 변경하기위한 것입니다. – CAD97

+0

렉싱/파싱이 시작되기 전에 어떻게이 '런타임 구성'을 알 수 있습니까? – cantSleepNow

+0

@cantSleepNow 예, 각 런타임 이전에 알려져 있고 상수입니다. – CAD97

답변

0

이 질문에 대한 답변이 될 수는 없지만 설명하기에는 너무 길다.
나는이 부분에 초점을 맞추기 때문에 주석에서 렉서 모드를 의미했습니다. hot-swap keywords. 토큰 유형을 변경해야하는 이유는 모르겠지만 렉서 모드를 사용하면 걱정하지 않아도됩니다.

유일한 어법은 렉서 모드 변경을 나타내는 몇 가지 키워드가 있어야한다는 것입니다. 기본적으로 하나의 렉서 모드는 하위 렉서 문법 (일종의 것입니다.)

RUNTIME_CFG_! : 'runtime_cfg_1' -> mode(m_CGF_1); 
... 
mode m_CGF_1; 
KEYWORD1 : 'key1; 
... 

당신이 명시 적으로 토큰의 유형을 설정 * 렉서 기능 type를 사용할 수있는 몇 가지 동일한 키워드가있는 경우.

* 내가 mode, skip 등 같은 그 중 하나 뜻이라고 어떻게 그 순간에 있지만, 렉서 기능에 의해 기억이 안나요 .. 나는이 작업을 위해 찾을 수있는 가장 유망한 기호는`org.antlr이