Engee 文档
Notebook

计算算术表达式

此示例演示如何使用内置Julia解析器来分析和计算算术表达式。

导言

算术表达式的计算是将数学表达式的字符串表示转换为可以解释和计算的数据结构的过程。 它是许多软件系统的关键元素,如计算器,编译器和解释器。

此过程通常涉及两个主要步骤:

  1. 解析-将字符串转换为[抽象句法дерево](https://ru.wikipedia.org/wiki/Абстрактное_синтаксическое_дерево )(AST)
  2. 计算-遍历树并进行数学运算

这种方法用于:

-编程语言的编译器和解释器
-数学计算器
-计算机代数系统
-科学计算中的数学表达式分析

使用Julia中的表达式

Julia提供了用于处理表达式并计算它们的内置函数。 功能 Meta.parse() 将带有代码的字符串转换为类型的对象 Expr (expression),这是一个抽象的语法树。

In [ ]:
# Определяем строку с арифметическим выражением
expr = "2 * (3 -1) + 2 * 5"
Out[0]:
"2 * (3 -1) + 2 * 5"
In [ ]:
# Преобразуем строку в выражение (AST)
parsed = Meta.parse(expr) # Julia предоставляет низкоуровневый доступ к парсеру языка для создания AST/Expr
Out[0]:
:(2 * (3 - 1) + 2 * 5)

解析后,我们得到一个类型的对象 Expr,这是一个抽象语法树(AST)。 这是一个树结构,其中每个节点对应于一个操作或操作数。

In [ ]:
# Получаем тип объекта
t = typeof(parsed)
Out[0]:
Expr

类型的对象 Expr 有字段:

  • :head -节点类型(例如,加法运算:+)
  • :args -节点参数(操作数)
In [ ]:
# Просматриваем поля типа Expr
fieldnames(t) # показывает поля типа
Out[0]:
(:head, :args)

我们的主要领域是 args,其中包含表达式的参数。
对于我们的表达式,第一个参数是操作符号。 :+,其余的参数是子表达式。

In [ ]:
# Исследуем внутреннюю структуру объекта 'Expr'
parsed.args # Инспектируем содержимое типа 'Expr'
Out[0]:
3-element Vector{Any}:
 :+
 :(2 * (3 - 1))
 :(2 * 5)

如您所见,表达式可以嵌套。 我们表达式的第二个参数也是类型的对象 Expr.

In [ ]:
# Типы 'Expr' могут быть вложенными
typeof(parsed.args[2])
Out[0]:
Expr
In [ ]:
# Смотрим аргументы вложенного выражения
parsed.args[2].args
Out[0]:
3-element Vector{Any}:
  :*
 2
  :(3 - 1)

深入树下,我们到达最基本的元素-数字和简单的操作。

In [ ]:
# Продолжаем спускаться до самого нижнего уровня AST
parsed.args[2].args[3].args # Будет вкладываться до самого низкого уровня AST
Out[0]:
3-element Vector{Any}:
  :-
 3
 1

最后,当树构建时,我们可以使用函数计算结果 eval().

In [ ]:
# Вычисляем выражение
eval(parsed)
Out[0]:
14

其他示例

让我们演示该算法如何在其他表达式上工作。:

In [ ]:
# Более сложное выражение с делением
eval(Meta.parse("1 - 5 * 2 / 20 + 1"))
Out[0]:
1.5
In [ ]:
# Выражение с несколькими уровнями вложенности скобок
eval(Meta.parse("2 * (3 + ((5) / (7 - 11)))"))
Out[0]:
3.5

结论

我们已经回顾了Julia中计算算术表达式的算法的实现,使用内置的语言功能来解析和计算表达式。

我们成功了:

  1. 将数学表达式的字符串表示形式转换为抽象语法树(AST)

  2. 调查生成的树的结构

  3. 执行表达式的计算,同时考虑到操作和括号的优先级。

这种方法对于:

-创建数学计算器
-DSL(领域特定语言)开发
-构建编译器和解释器
-科学应用中的数学表达式的分析和处理

该示例是使用[Rosetta代码]的材料开发的(https://rosettacode.org/wiki/Arithmetic_evaluation