1

私は単純なコンパイラ プログラムに 1 日を費やしましたが、まだこの機能を理解するのに苦労しています。

let rec expression tokens = 
  let (trm, tokens') = term tokens in 

ここで (trm, tokens') はタプルですが、term は関数ですか、それとも変数ですか? タプル = 2 つの変数または関数

  expTail trm tokens'

and
  expTail trm tokens = 
  match tokens with
    Tokenizer.PlusTok::tokens' ->
      let (trm', tokens'') = term tokens' in expTail (Plus(trm, trm')) tokens''

  | Tokenizer.MinusTok::tokens' ->
      let (trm', tokens'') = term tokens' in expTail (Minus(trm, trm')) tokens''

  |  _ -> (trm, tokens)

この行はどういう意味ですか?何も呼ばないようです。そして、なぜ (trm', tokens'') ではなく (trm', tokens'') なのか

and
  term tokens = let (trm, tokens') = factor tokens in termTail trm tokens'

この行の意味もよくわかりません。

and
  termTail trm tokens =
  match tokens with
    Tokenizer.TimesTok::tokens' -> 
      let (trm', tokens'') = factor tokens' in termTail (Times(trm, trm')) tokens''

  | Tokenizer.DivTok::tokens' -> 
      let (trm', tokens'') = factor tokens' in termTail (Div(trm, trm')) tokens''

  | Tokenizer.ModTok::tokens' -> 
      let (trm', tokens'') = factor tokens' in termTail (Mod(trm, trm')) tokens''

  | _ -> (trm, tokens)

and
  factor tokens =
  match tokens with
  Tokenizer.LParenTok::tokens' -> 
  let (expr, tokens'') = expression tokens' in
      (match tokens'' with
      Tokenizer.RParenTok::tokens''' -> (expr, tokens''')
  | _ -> raise (Syntax "Bad factor, failed to find )\n")) 

  | (Tokenizer.IntTok i)::tokens' -> (Bits i,  tokens')

  | _ -> raise (Syntax ("Bad factor."))

みんなありがとう!

4

1 に答える 1

1

これらはかなり基本的な質問です。OCaml チュートリアルから始めるのが良いかもしれません (以前の SO の質問OCaml Resources?を参照してください)。

いくつかの答え:

let (trm, tokens') = term tokens

これは、termpassingという名前の関数をtokens引数として呼び出します。結果はペアです。ペアの最初の要素を name で参照し、trm2番目の要素を name で参照しtokens'ます。

and
   term tokens = let (trm, tokens') = factor tokens in termTail trm tokens'

これらは、term上記で呼び出された関数を定義する行です。

  |  _ -> (trm, tokens)

これは、パターン マッチのデフォルトのケースです。他の 2 つのパターンのいずれも一致しない場合、値はこの選択肢によって与えられます。これは基本的に値であり、関数呼び出しではありません。ただし、ある意味では、ペアを構築しているという機能が関係しています。コンマ ( ,) は、ペアを作成するための適切な構文として使用されます。(括弧は実際には省略可能ですが、文体的には私はそれらを見るのが好きです。)

名前tokenstokens'は単に別の名前です。それらの間に固有の関係はありません。このデフォルトのケースでは、指定された値tokens'は定義されていません。したがって、ここでそのような値を参照することはできません。従来、名前の末尾に「プライム」を追加することは、新しい値が古い値から派生したものであることを示すために使用されます。

于 2012-10-20T19:21:48.267 に答える