4

这是来自解析器模块的函数。我无法理解一行代码

 let rec e1 tokens =
   match tokens with
    Tokenizer.IfTok :: tokens1 -> 
      let (testAST, tokens2) = e1 tokens1
      in
      (match tokens2 with
          Tokenizer.ThenTok :: tokens3 ->
            let (thenAST, tokens4) = e1 tokens3
            in
            (match tokens4 with
                Tokenizer.ElseTok :: tokens5 ->
                  let (elseAST, tokens6) = e1 tokens5 
                  in
                  (If(testAST, thenAST, elseAST), tokens6)
              | _ -> raise (Syntax ("e1: missing else.")))
        | _ -> raise (Syntax ("e1: missing then.")))
  | _ -> e2 tokens

and e2 tokens = ........

我不知道这条线是如何工作的

let (testAST, tokens2) = e1 tokens1 in

我知道它声明了一个局部变量,它是一个元组,但是值 (testAST, tokens2) 来自哪里?它似乎与令牌或令牌1没有任何关系。此行是否仅声明一个元组或它也调用该函数?谢谢!

4

2 回答 2

3

是的,这一行确实声明了两个变量并调用了函数e1,将变量绑定到函数调用的结果。

这种绑定变量的方式称为模式匹配。它基于函数返回类型的信息e1——编译器知道它返回一个元组,然后它可能被分解为多个部分,这些部分绑定到两个新变量,testAST并且tokens2. 它是 FP 最强大的功能之一,它使您可以编写更易读、更灵活、更简洁的代码。

如果编译器知道该实体(模式)的结构(例如,Scala 中的案例类、Haskell 中的元组和列表、Erlang 中的记录等),也可以在所有内容上完成(匹配)。模式匹配也可用于忽略与条件无关的结构的某些部分(例如,在 Haskell 中,如果您想选择三元组中的第二项,只需执行,其中是用于忽略值的特殊符号)。selectSecond (_, a, _) = a_

于 2012-10-29T23:11:03.557 回答
0

它正在调用一个名为e1. 事实上,这正是它出现的功能;即,它是对e1. 该函数返回一对(一个 2 元组)。

这看起来像非常标准的递归下降解析

于 2012-10-29T23:00:26.380 回答