追加 if 列表中的元素
append if element in list
我正在尝试为程序创建解析器。例如,
我输入了(我想要的)
"(2+3)-4" it will become something like this "(minus, (plus, num 2, num 3),num 4)"
到目前为止我做了什么..
"(2+3)-4" I then split it and it becomes list Z = ["(","2","+","3",")","-","4"] then I compared if "-" is a member of Z, if true I append the element "-" into a new list ["-"]
我不确定我的做法是否正确,我是 Er-lang 的新手并且很挣扎。如果有人能给我一些见解,谢谢。
考虑以下内容,returns 其输入的基于元组的表示:
parse(Expr) ->
Elems = re:split(Expr, "([-+)(])", [{return,list}]),
parse(lists:filter(fun(E) -> E /= [] end, Elems), []).
parse([], [Result]) ->
Result;
parse([], [V2,{op,Op},V1|Tacc]) ->
parse([], [{Op,V1,V2}|Tacc]);
parse(["("|Tail], Acc) ->
parse(Tail, [open|Acc]);
parse([")"|Tail], [Op,open|TAcc]) ->
parse(Tail, [Op|TAcc]);
parse(["+"|Tail], Acc) ->
parse(Tail, [{op,plus}|Acc]);
parse(["-"|Tail], Acc) ->
parse(Tail, [{op,minus}|Acc]);
parse([V2|Tail], [{op,Op},V1|Tacc]) ->
parse(Tail, [{Op,V1,{num,list_to_integer(V2)}}|Tacc]);
parse([Val|Tail], Acc) ->
parse(Tail, [{num,list_to_integer(Val)}|Acc]).
第一个函数 parse/1
沿 +
和 -
运算符和括号拆分表达式,将它们保留在结果列表中。然后过滤该列表以删除空元素,并将其与空累加器一起传递给 parse/2
.
parse/2
函数有八个子句,描述如下:
- 前两个处理解析的输入列表已用尽的情况。其中第二个处理累加器中的多个元素需要折叠成一个由运算符和操作数组成的元组的情况。
- 下两个句柄子句括号。当我们看到一个左括号时,我们将一个原子
open
压入累加器。看到匹配的右括号后,我们希望在累加器中看到一个操作元组和原子 open
,我们只用元组替换它们。
- 第 5 条和第 6 条分别处理
+
和 -
。每个只是将一个 {op,Operator}
元组推入累加器,其中 Operator
是原子 plus
或原子 minus
.
- 最后两个子句处理值。第一个处理累加器保存一个值和一个
op
元组的情况,它被一个完整的操作元组替换,该元组由原子 plus
或 minus
后跟两个 num
元组,每个元组都包含整数操作数。最后一个子句只处理普通值。
将其放入模块 p
中,对其进行编译,然后 运行 在 Erlang shell 中生成以下内容:
1> p:parse("2+3").
{plus,{num,2},{num,3}}
2> p:parse("(2+3)-4").
{minus,{plus,{num,2},{num,3}},{num,4}}
我正在尝试为程序创建解析器。例如, 我输入了(我想要的)
"(2+3)-4" it will become something like this "(minus, (plus, num 2, num 3),num 4)"
到目前为止我做了什么..
"(2+3)-4" I then split it and it becomes list Z = ["(","2","+","3",")","-","4"] then I compared if "-" is a member of Z, if true I append the element "-" into a new list ["-"]
我不确定我的做法是否正确,我是 Er-lang 的新手并且很挣扎。如果有人能给我一些见解,谢谢。
考虑以下内容,returns 其输入的基于元组的表示:
parse(Expr) ->
Elems = re:split(Expr, "([-+)(])", [{return,list}]),
parse(lists:filter(fun(E) -> E /= [] end, Elems), []).
parse([], [Result]) ->
Result;
parse([], [V2,{op,Op},V1|Tacc]) ->
parse([], [{Op,V1,V2}|Tacc]);
parse(["("|Tail], Acc) ->
parse(Tail, [open|Acc]);
parse([")"|Tail], [Op,open|TAcc]) ->
parse(Tail, [Op|TAcc]);
parse(["+"|Tail], Acc) ->
parse(Tail, [{op,plus}|Acc]);
parse(["-"|Tail], Acc) ->
parse(Tail, [{op,minus}|Acc]);
parse([V2|Tail], [{op,Op},V1|Tacc]) ->
parse(Tail, [{Op,V1,{num,list_to_integer(V2)}}|Tacc]);
parse([Val|Tail], Acc) ->
parse(Tail, [{num,list_to_integer(Val)}|Acc]).
第一个函数 parse/1
沿 +
和 -
运算符和括号拆分表达式,将它们保留在结果列表中。然后过滤该列表以删除空元素,并将其与空累加器一起传递给 parse/2
.
parse/2
函数有八个子句,描述如下:
- 前两个处理解析的输入列表已用尽的情况。其中第二个处理累加器中的多个元素需要折叠成一个由运算符和操作数组成的元组的情况。
- 下两个句柄子句括号。当我们看到一个左括号时,我们将一个原子
open
压入累加器。看到匹配的右括号后,我们希望在累加器中看到一个操作元组和原子open
,我们只用元组替换它们。 - 第 5 条和第 6 条分别处理
+
和-
。每个只是将一个{op,Operator}
元组推入累加器,其中Operator
是原子plus
或原子minus
. - 最后两个子句处理值。第一个处理累加器保存一个值和一个
op
元组的情况,它被一个完整的操作元组替换,该元组由原子plus
或minus
后跟两个num
元组,每个元组都包含整数操作数。最后一个子句只处理普通值。
将其放入模块 p
中,对其进行编译,然后 运行 在 Erlang shell 中生成以下内容:
1> p:parse("2+3").
{plus,{num,2},{num,3}}
2> p:parse("(2+3)-4").
{minus,{plus,{num,2},{num,3}},{num,4}}