2017-05-04 8 views
1

Javaccを使って言語構文を作成するのはとても新しく、ユーザーがコード内でトークンの定義を再定義できるようにする必要があります。どうなるかたとえばJavaccを使って字句トークンを再定義する

、これが不可能な場合

REDEFINE IF FOO 

は、 "IF" から

< IF: "IF" > 

< IF: "FOO" > 

の定義を変更する必要がありますライン、この問題を解決する最良の方法は?

答えて

1

トークンの種別フィールドを変更するトークンアクションを使用するといいと思います。

次のようなものです。 [未定のコードが続きます。あなたはそれを使用している場合は、この答えではすべてのエラーを修正してください]

をハッシュマップのトークンマネージャの宣言を行います。

TOKEN_MGR_DECLS: { 
    public java.util.HashMap<String,Integer> keywordMap = new java.util.HashMap<String,Integer>() ; 
    { keywordMap.put("IF", ...Constants.IF); } 
} 

識別子の定義を行います。

TOKEN : { <ID : (["a"-"z","A"-"Z"])(["a"-"z","A"-"Z","0"-"9"])* > 
       { if(keywordMap.containsKey(matchedToken.image)) { 
        matchedToken.kind = keywordMap.get(matchedToken.image) ; } 
       } 
     } 

キーワードの定義を行います。これらはIDの定義の後に来る必要があります。本当にこれらはちょうどここにあるので、種類が作られます。彼らは到達不能になり、警告を発する可能性があります。あなたは

void redefine() : 
{ 
    Token oldToken; 
    Token newToken; 
} 
{ 
    <REDEFINE> oldToken=redefinableToken() newToken=redefinableToken() 
    { 
     if(...TokenManager.keywordMap.containsKey(oldToken.image)) { 
      ...TokenManager.keywordMap.remove(oldToken.image) ; 
      ...TokenManager.keywordMap.add(newToken.image, oldToken.kind) ; } 
     else { 
      report an error } 
    } 
} 

Token redefinableToken() : 
{ Token t ; } 
{ 
    t=<ID> {return t ;} 
| t=<IF> {return t ;} 
| ... 
} 

を再定義定義する必要がパーサで

TOKEN : { <IF : "A"> | ... } 

は、パーサーからレクサーの動作を変更しようとしているについての警告のためのFAQ(4.14)を参照してください。長い話が短いです:先読みを避けてください。


別のアプローチは、単に、1トークン種類を持ってIDを言うと、パーサのすべてを処理することです。 「キーワードを意味的先読みで置き換える」のFAQ 4.19を参照してください。構文解析先読み(FAQ 4.10)中にパーサーの意味アクションが実行されないので、先読みはあまり問題になりません。

+0

返信いただきありがとうございました。パーサーを通してキーワードマップを参照しているときに問題が発生しています(トークン定義の場合)。 - 未解決のコンパイルの問題:keywordMapを解決できないか、フィールドではありません。 –

+0

更新:私はこの問題を解決しました。私はまだコメントしましたが、まだ別の問題がありますが、修正してください。すぐに副作用 –

+0

非常にこのソリューションはいくつかのマイナーな微調整と非常によく働いてくれてありがとう:) –

関連する問題