0

プロジェクトのクラス名がわかっているなど、いくつかの既知の識別子名を文法に埋め込みたいのですが、どの識別子が実際にクラス名トークンに属する既知のキーワードであるかをレクサーに伝えたいと考えています。しかし、クラス名の長いリスト (何百もの名前) があるため、ルール内のすべての既知のクラス名キーワードをリストしてクラス名レクサー ルールを作成したくありません。これにより、文法ファイルが大きくなりすぎます。

キーワードを別のファイルに入れることはできますか? 私が考えている 1 つの可能性は、生成されたレクサー クラスによってサブクラス化される Java クラスにキーワードを配置することです。その場合、レクサーのセマンティック述語は、カスタム レクサー スーパークラスのメソッドを呼び出すだけで、入力トークンが名前の長いリストと一致するかどうかを確認できます。私の長いリストは、そのスーパークラスの src コード内に配置できます。

ただし、ANTLR4の本では、組み合わせた文法の文法オプション「superClass」はパーサーのスーパークラスのみを設定すると述べています。複合文法を使用したい場合、レクサーのスーパークラスを設定するにはどうすればよいですか。または、キーワードの長いリストを別の「キーワード ファイル」に入れるための他のより良い方法はありますか。

4

1 に答える 1

1

各キーワードに独自のトークン タイプを持たせたい場合は、次の操作を実行できます。

  1. 文法にブロックを追加してtokens{}、各キーワードのトークンを作成します。これにより、キーワードごとに一意のトークン タイプが作成されます。

    tokens {
        Keyword1,
        Keyword2,
        ...
    }
    
  2. MyLanguageKeywords次のような別のクラスを作成します。

    private static final Map<String, Integer> KEYWORDS =
        new HashMap<String, Integer>();
    static {
        KEYWORDS.put("keyword1", MyLanguageParser.Keyword1);
        KEYWORDS.put("keyword2", MyLanguageParser.Keyword2);
        ...
    }
    
    public static int getKeywordOrIdentifierType(String text) {
         Integer type = KEYWORDS.get(text);
         if (type == null) {
             return MyLanguageParser.Identifier;
         }
    
         return type;
    }
    
  3. Identifierキーワードと識別子を処理する文法規則を文法に追加します。

    Identifier
        :   [a-zA-Z_] [a-zA-Z0-9_]*
            {_type = MyLanguageKeywords.getKeywordOrIdentifierType(getText());}
        ;
    
于 2013-05-07T13:17:33.970 に答える