首页 > 代码库 > 解释抽象语法树

解释抽象语法树

解释抽象语法树

 

创建了抽象语法树之后,有两个选择:解释或编译。解释,简单地说,就是遍历树,同时执行操作;编译,就是改变成其他形式,对于机器执行来说可能更简单,通常可能更快。这一小节先讨论如何解释结果,下面一小节再讨论编译的内容,最后,再讨论何时应该用解释,何时应该用编译的问题。

下面的例子是一个很小解释器,解释抽象语法树的主要工作由函数interpret 完成,它遍历树,并同时执行需要的动作。逻辑相当简单,如果发现一个文字值或标识符,就返回相应值:

 

| Ident (s) ->variableDict.[s]

| Val (v) -> v

 

如果找到的是一个运算对象,就递归地评估算获得这个值的表达式,并执行运算:

 

| Multi (e1, e2) -> (interpretInner e1) *(interpretInner e2)

 

清单 12-6 是完整的解释器程序。

 

清单 12-6 解释由命令行输入产生的抽象语法树

 

openSystem.Collections.Generic

openStrangelights.ExpressionParser.Ast

 

// requesting a value for variable fromthe user

let getVariableValuese =

  let rec getVariableValuesInnerinput (variables : Map<string, float>) =

    match input with

    | Ident (s) ->

      matchvariables.TryFind(s) with

      | Some _ ->variables

      | None ->

        printf "%s:" s

        let v = float(Console.ReadLine())

        variables.Add(s,v)

    | Multi (e1, e2) ->

      variables

      |> getVariableValuesInner e1

      |> getVariableValuesInner e2

    | Div (e1,e2) ->

      variables

      |> getVariableValuesInner e1

      |> getVariableValuesInner e2

    | Plus (e1, e2) ->

      variables

      |> getVariableValuesInner e1

      |> getVariableValuesInner e2

    | Minus (e1, e2) ->

      variables

      |>getVariableValuesInner e1

      |> getVariableValuesInner e2

    | _ ->variables

  getVariableValuesInnere (Map.Empty())

 

// function to handle the interpretation

let interpret input(variableDict : Map<string,float>) =

  let rec interpretInner input =

    match input with

    | Ident (s) ->variableDict.[s]

    | Val (v) ->v

    | Multi (e1, e2) ->(interpretInner e1) * (interpretInner e2)

    | Div (e1, e2) ->(interpretInner e1) / (interpretInner e2)

    | Plus (e1, e2) ->(interpretInner e1) + (interpretInner e2)

    | Minus(e1, e2) -> (interpretInner e1) -(interpretInner e2)

  interpretInnerinput

 

// the expression to be interpreted

let e = Multi(Val 2.,Plus(Val 2., Ident "a"))

 

// collect the arguments from the user

let args =getVariableValues e

 

// interpret the expression

let v = interpret eargs

 

// print the results

printf "result:%f" v

 

编译并运行前面的结果如下:

 

[a]: 12

result: 28.000000