2017-03-25 9 views
1

私は現在、ハッピー&アレックスを使って、おもちゃの言語 のコンパイラのパーサを書いています。任意のレイアウトのオプションが必要なので、私は アレックスの状態をblock非端末に合わせる前に変更しなければなりません。残念ながら ハッピーに必要な先読みトークンが先に読み取られているようです 私はアレックスの状態を変更するチャンスがあります。ここでハッピー&アレックス - 先読みがパーサーレクサーの通信に影響を与えないようにする

は、問題を実証する小さなスニペットです:

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

は、この問題に対する一般的なアプローチはありますか?

+0

ブロックの開始位置をどのように知っていますか?私は 'localDefs'は自己終了していないと仮定しているので、ブロックの開始位置を知るために使うことができる字句機能がなければなりません。おそらく少し解明できますか? – rici

+0

@riciブロックはbegin/endキーワードで囲まれているか、またはインデントベースです。基本的にbegin stmts + endまたはstmts autoendとして定義されています。レクサーは、識別変更が検出されたときに自動応答を生成するために、開始が欠落していることを通知する必要があります。全体のアプローチは、より良い方法でなければならない非常にハッキリと感じています。 –

+0

2週間前にこの_exact_問題を解決しました。他の誰かがその上を走るとは思わなかった。 – Alec

答えて

0

スレッドレクサーを使用していると仮定しています(HappyとAlexは同じモナドで動作しています)。私が同様の問題に直面したときに使用したトリックは、空のプロダクションルールをルールに入れることです。

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 definedおよびhere is where I "pop" tokens。それがどうなるか教えてください!

関連する問題