2

コード内の型を読み込み/出力するために、レクサー/パーサー/プリティプリンターの通常の組み合わせを実装しました。通常、記号、句読点、またはセパレーターに使用されるプレーン文字列の正規表現に関しては、レクサーとプリティプリンターの間に冗長性があることがわかりました。

たとえば、私は今持っています

rule token = parse
  | "|-" { TURNSTILE }

私のlexer.mllファイルで、次のような関数:

let pp fmt (l,r) = 
  Format.fprintf fmt "@[%a |-@ %a@]" Form.pp l Form.pp r

きれいな印刷用。TURNSTILE の文字列を変更することにした場合、コード内の 2 つの場所を編集する必要がありますが、これは理想的とは言えません。

どうやら、OCaml lexer は、正規表現を定義し、ファイル内でmllそれらを参照する特定の機能をサポートしています。したがってlexer.mll、次のように書くことができます

let symb_turnstile = "|-"

rule token = parse
  | symb_turnstile { TURNSTILE }

しかし、これでは外部からアクセスすることはできませんsymb_turnstile。たとえば、きれいな印刷機能からです。実際、 を実行した後、 inocamllexは発生しません。の OCaml エピローグでこれらの識別子を参照することさえできません。symb_turnstilelexer.mllexer.mll

これを達成する方法はありますか?

4

2 に答える 2

4

結局、私はそれ自体の情報源から盗んだ次のスタイルに行きましたocamllex(したがって、それが標準的な方法であると推測しています)。文字列からトークン (ここでは連想リスト) へのマップは、のプリアンブルで定義されています。lexer.mll

let symbols =
  [ 
    ...
    (Symb.turnstile, TURNSTILE); 
    ...
  ]

ここで、文字列としてSymb定義するモジュールです。turnstile次に、 の語彙部分lexer.mllは意図的に過度に一般的です。

rule token = parse
  ...
  | punctuation
    {
      try 
        List.assoc (Lexing.lexeme lexbuf) symbols
      with Not_found -> lex_error lexbuf  
    }
  ...

ここpunctuationで、一連の記号に一致する正規表現です。

pretty-printer は次のように記述できるようになりました。

let pp fmt (l,r) = 
  Format.fprintf fmt "@[%a %s@ %a@]" Form.pp Symb.turnstile l Form.pp r
于 2012-08-05T10:26:11.423 に答える
1

Although the two tokens both look like strings notationally, they're really very different. I don't think there's a convenient type under which they could be shared for use by ocamllex and Printf.printf. This is possibly the reason that ocamllex doesn't support such external definitions. You could get probably the effect you want with a macro facility (textual inclusion).

于 2012-08-03T15:31:09.263 に答える