我花了一天时间尝试一个简单的编译器程序,但仍然难以理解这个函数。
let rec expression tokens =
let (trm, tokens') = term tokens in
这里(trm,tokens')是一个元组,是一个函数还是一个变量?元组如何=两个变量或一个函数
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."))
谢谢你们!
答案 0 :(得分:1)
这些都是非常基本的问题。从OCaml教程开始可能会很好(可能会看到之前的SO问题OCaml Resources?)。
一些答案:
let (trm, tokens') = term tokens
这将调用名为term
的函数作为参数传递tokens
。结果是一对。您将使用名称trm
引用该对中的第一个元素,并使用名称tokens'
引用第二个元素。
and
term tokens = let (trm, tokens') = factor tokens in termTail trm tokens'
这些是定义上面调用的term
函数的行。
| _ -> (trm, tokens)
这是模式匹配的默认情况。如果其他两个模式都不匹配,则该替代值给出该值。这基本上是一个值,而不是函数调用。但是,在某种意义上,涉及到一个功能 - 您构建一对。逗号(,
)用作构造对的很好的语法。 (括号实际上是可选的,虽然在风格上我喜欢看它们。)
名称tokens
和tokens'
只是名称不同。它们之间没有内在联系。在此默认情况下,未定义名为tokens'
的值。所以这里不可能引用这样的值。通常,在名称的末尾添加“prime”用于表示新值以某种方式从旧名称派生。