如何将中缀转换成后缀在erlang? [英] How to convert infix to postfix in erlang?

查看:95
本文介绍了如何将中缀转换成后缀在erlang?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚发现了这个发布,这是非常优雅的。

I just came across this post,it's quite elegant.

但是它没有考虑到不同运营商的优先级。

But it's not taking into account the priority of different operators.

例如 * 的优先级高于 +

所以 1 + 2 *(3 + 2)应转换为 1 2 3 2 + * +

如何在erlang中考虑优先级问题?

How to do it in erlang taking the priority issue into account?

推荐答案

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

Here is a way to do it which abuses the built-in parser for Erlang terms. You could write your own parser via yecc or recursive descent, but for the simplicity, I'll stick with the Erlang-parser.

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

声明一个模块,从中导出所有内容。如果你想使用它,这是不好的形式。相反,最小化导出到 p / 1

Declare a module, export everything from it. This is bad form if you want to use this. Rather minimize the export to p/1.

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

此函数滥用Erlang解析器,以便我们可以获取Erlang令牌的解析树。

This function abuses the Erlang parser so we can get a parse tree of Erlang tokens.

 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或者使用基于解析器组合器和/或递归下降的解析器。特别是这个简单的语法。

RPN output is to do a post-order tree-walk traversal. So we basically walk the Left hand and right hand side of the tree and then output ourselves as a node. The order of "parenthesis" is stored abstractly in the tree itself. The priority is handled by the Erlang parser. You could easily do this via a recursive descent parser if you want. But that is a different question to the point of "How do I write parsers in Erlang?" The answer is twofold: Either you use leex+yecc or you use a parser based upon parser combinators and/or recursive descent. Especially for a grammar this simple.

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

这只是格式化。

这篇关于如何将中缀转换成后缀在erlang?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆