erlang - erlang中如何将中缀转换为后缀?

标签 erlang

我刚刚遇到this post ,相当优雅。

但是没有考虑到不同算子的优先级。

例如* 的优先级高于 +

因此 1+2*(3+2) 应转换为 1 2 3 2 + * +

考虑到优先级问题,在erlang中如何做到这一点?

最佳答案

这里有一种方法,它滥用了 Erlang 术语的内置解析器。您可以通过 yecc 或递归下降编写自己的解析器,但为了简单起见,我将坚持使用 Erlang 解析器。

  -module(foo).
  -compile(export_all).

声明一个模块,从中导出所有内容。如果你想使用它,这是不好的形式。而是尽量减少对 p/1 的导出。

 parse(Str) ->    
     {ok, Tokens, _} = erl_scan:string(Str ++ "."),
     {ok, [E]} = erl_parse:parse_exprs(Tokens),
     E.

这个函数滥用了 Erlang 解析器,因此我们可以获得 Erlang 标记的解析树。

 rpn({op, _, What, LS, RS}) ->
     rpn(LS),
     rpn(RS),
     io:format(" ~s ", [atom_to_list(What)]);
 rpn({integer, _, N}) ->
     io:format(" ~B ", [N]).

RPN 输出是进行后序树遍历。因此,我们基本上遍历树的左侧和右侧,然后将自己输出为节点。 “括号”的顺序抽象地存储在树本身中。优先级由 Erlang 解析器处理。如果需要,您可以通过递归下降解析器轻松完成此操作。但这与“如何在 Erlang 中编写解析器?”的问题不同。答案是双重的:要么使用 leex+yecc,要么使用基于解析器组合器和/或递归下降的解析器。特别是对于如此简单的语法。

 p(Str) ->
      Tree = parse(Str),
      rpn(Tree),
      io:format("~n").

这只是格式化。

关于erlang - erlang中如何将中缀转换为后缀?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7242315/

相关文章:

python - 我如何从 Python 调用 erlang?

erlang - 尝试指定 :env in Elixir Port. 打开时出现参数错误

configuration - 如何定义配置文件变量?

erlang - 访问二进制中的变量位位置 - Erlang

database - Erlang:2 个网络服务器上的 2 个数据库?

docker - 在docker上连接erlang节点

sockets - WhatsApp 如何实现每台服务器 200 万个连接?

python - Erlang 和 Python 之间的 RSA 加密

transactions - Erlang Mnesia - mnesia :transaction(F) vs. mnesia :activity(transaction, F)

使用 fprof 对 CPU 时间进行 Erlang 性能分析