2016-10-30 10 views
1

私がレキシングしている言語には、ランタイム構成に応じてキーワードをホットスワップする機能が必要です。ANTLR4動的トークンタイプ

それはあなたの文法(Java)の中でターゲット固有のコードを埋め込むので、限り、あなたはOKですとしてこれを行う方法は比較的簡単です:

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を作成すると、それを既存のライブラリに追加することをお勧めしますか? (私はすべての現在の供給目標のためのシンボルを作成することができます。)


をはい、これはあなたが定期的にコンストラクタでレクサーを構築した場合にクラッシュします。実際のアプリケーションでは、それを修正する価値があるかもしれませんが、この例では問題ではありません。

これは、いくつかの理由から、これはレクサーレベルにとって適切な作業だと思います。主な理由は、キーワードを常にキーワードトークンとして渡し、必要に応じて、パーサーレベルで識別子として使用できるようにすることです(状況依存キーワードなど)。また、他の質問は単にこの効果を達成する方法は、上記の提供された組み込みアクションのソリューションと基本的に同等の方法を示唆する示唆する。

+0

です.v4.runtime.TokenStreamRewriter'ですが、javadocを正しく読み込んでいる場合は、テキスト表現を変更するためだけです。 – CAD97

+0

字句解析/構文解析が始まる前に、この「実行時設定」を何とか知っていますか? – cantSleepNow

+0

@cantSleepNowはい、それは各実行時の前と定数で知られています。 – CAD97

答えて

0

これは質問の答えにはならないかもしれませんが、コメントするには長すぎます。
私はこの部分に焦点を当てていたので、コメントのレクサーモードを意味しましたhot-swap keywords。なぜトークンタイプを変更する必要があるのか​​わかりませんが、レクサーモードを使用している場合は気にしません。

唯一のキャッチは、レクサーモードの変更を示すキーワードが必要であることです。基本的に1つのレクサーモードは、サブレクサー文法(ある種のものです。)

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

いくつかの同じキーワードがある場合、あなたはまた、明示的にトークンの種類を設定する*レクサー機能typeを使用することができます。

*私はmodeskipなどのような人々の1を意味し、それは呼ばれていますどのように一瞬ではなく、レクサー機能で思い出すことができない..私は、このタスクのために見つけることができる最も有望なシンボルは `org.antlrが