2

私の現在のプロジェクトには、スクリプト コードの字句解析と解析が含まれているため、fslex と fsyacc を使用しています。Fslex LexBuffers にはいずれかLexBuffer<char>LexBuffer<byte>種類があり、両方を使用するオプションが必要です。

両方を使用するには、タイプ ^buf -> string の語彙素関数が必要です。これまでのところ、私の専門化の試みは次のようになっています。

let inline lexeme (lexbuf: ^buf) : ^buf -> string where ^buf : (member Lexeme: char array) =
  new System.String(lexbuf.Lexeme)

let inline lexeme (lexbuf: ^buf) : ^buf -> string where ^buf : (member Lexeme: byte array) =
  System.Text.Encoding.UTF8.GetString(lexbuf.Lexeme)

関数本体の型は である必要があるという型エラーが表示されます^buf -> stringが、推定される型は ですstring。明らかに、私は何か(主に?) 間違っています。

私が試みていることはF#でも可能ですか? もしそうなら、誰かが私に適切な道を教えてもらえますか?

ありがとう!

4

3 に答える 3

2

としてマークされた関数とメンバーはinlineオーバーロードできないため、元の戦略は機能しません。両方の宣言に対して異なるコードを記述する必要があるため、オーバーロードを使用する必要があります(ボクシングや動的型テストなしでこれを記述したい場合)。

標準のF#ツールを使用している場合、バッファーとして取得する型は常にでLexBuffer<'T>あり、type引数に基づいて2つのオーバーロードが必要です。この場合、静的メンバーの制約はまったく必要なく、次のように書くことができます。

type Utils = 
  static member lexeme(buf:LexBuffer<char>) = 
    new System.String(buf.Lexeme)
  static member lexeme(buf:LexBuffer<byte>) = 
    System.Text.Encoding.UTF8.GetString(buf.Lexeme)
于 2010-12-21T13:11:52.467 に答える
0
type LexBuffer<'a>(data : 'a []) =
  member this.Lexeme = data

let lexeme (buf : LexBuffer<'a>) =
  match box buf.Lexeme with
  | :? (char array) as chArr ->
      new System.String(chArr)
  | :? (byte array) as byArr ->
      System.Text.Encoding.UTF8.GetString(byArr)
  | _ -> invalidArg "buf" "must be either char or byte LexBuffer"

new LexBuffer<byte>([| 97uy; 98uy; 99uy |])
|> lexeme
|> printfn "%A"

new LexBuffer<char>([| 'a'; 'b'; 'c' |])
|> lexeme
|> printfn "%A"
于 2010-12-21T12:33:22.137 に答える
0

inlineさまざまな引数の型を持つ関数を再定義するこの戦略がうまくいくと確信していますか? あなたは私に負担をかけようとしているようです...

于 2010-12-21T09:45:55.037 に答える