首页 > 代码库 > 解释抽象语法树
解释抽象语法树
解释抽象语法树
创建了抽象语法树之后,有两个选择:解释或编译。解释,简单地说,就是遍历树,同时执行操作;编译,就是改变成其他形式,对于机器执行来说可能更简单,通常可能更快。这一小节先讨论如何解释结果,下面一小节再讨论编译的内容,最后,再讨论何时应该用解释,何时应该用编译的问题。
下面的例子是一个很小解释器,解释抽象语法树的主要工作由函数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