解释抽象语法树

728 篇文章 1 订阅
86 篇文章 0 订阅

解释抽象语法树

 

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

下面的例子是一个很小解释器,解释抽象语法树的主要工作由函数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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值