You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何我的Erlang RPN计算器代码报‘Illegal guard expression’错误?

Erlang RPN计算器守卫表达式错误问题

我编写了一个简单的Erlang逆波兰表示法(RPN)计算器代码:

-module('Kalkulator_ONP').
-author("user").

%% API
-export([onp/1]).

onp(Expression) ->
  onp(string:tokens(Expression, " "),[]).

onp([], [Result]) ->
  Result;

onp([NumberString|Rest], Stack) when is_integer(string:to_integer(NumberString)) ->
  Number = string:to_integer(NumberString),
  onp(Rest, [Number|Stack]);

onp([Operator|Rest], [Number1, Number2|Stack]) when Operator == "+" ->
  onp(Rest, [Number1+Number2|Stack]);

onp([Operator|Rest], [Number1, Number2|Stack]) when Operator == "-" ->
  onp(Rest, [Number1-Number2|Stack]);

onp([Operator|Rest], [Number1, Number2|Stack]) when Operator == "*" ->
  onp(Rest, [Number1*Number2|Stack]);

onp([Operator|Rest], [Number1, Number2|Stack]) when Operator == "/" ->
  onp(Rest, [Number1/Number2|Stack]);

onp([Operator|Rest], [Number|Stack]) when Operator == "sqrt" ->
  onp(Rest, [math:sqrt(Number)|Stack]);

onp([Operator|Rest], [Number1, Number2|Stack]) when Operator == "^" ->
  onp(Rest, [math:pow(Number1, Number2)|Stack]);

onp([Operator|Rest], [Number|Stack]) when Operator == "sin" ->
  onp(Rest, [math:sin(Number)|Stack]);

onp([Operator|Rest], [Number|Stack]) when Operator == "cos" ->
  onp(Rest, [math:cos(Number)|Stack]);

onp([Operator|Rest], [Number|Stack]) when Operator == "tan" ->
  onp(Rest, [math:tan(Number)|Stack]).

其中onp([NumberString|Rest], Stack) when is_integer(string:to_integer(NumberString)) ->这一行被IntelliJ标红,提示Illegal guard expression错误,请问此处存在什么问题?


问题原因

  1. string:to_integer/1不属于守卫允许的内置函数:Erlang的守卫表达式(guard)有严格的语法限制,仅允许使用特定的内置函数(如is_integer/1、is_list/1等),普通函数调用不能出现在守卫中。
  2. 返回值逻辑错误:string:to_integer/1的返回值不是单纯的整数,解析成功时返回{Integer, 剩余字符串},失败时返回error,用is_integer/1判断这个元组或原子本身逻辑就不成立。

修正方案

把数字解析逻辑从守卫移到函数体内部,用case语句处理返回结果,同时确保整个字符串都是有效数字(剩余字符串为空):

-module('Kalkulator_ONP').
-author("user").

%% API
-export([onp/1]).

onp(Expression) ->
  onp(string:tokens(Expression, " "),[]).

onp([], [Result]) ->
  Result;

onp([NumberString|Rest], Stack) ->
    case string:to_integer(NumberString) of
        {Number, ""} -> onp(Rest, [Number|Stack]);
        _ -> error({invalid_token, NumberString})
    end;

onp([Operator|Rest], [Number1, Number2|Stack]) when Operator == "+" ->
  onp(Rest, [Number2 + Number1|Stack]);
onp([Operator|Rest], [Number1, Number2|Stack]) when Operator == "-" ->
  onp(Rest, [Number2 - Number1|Stack]);
onp([Operator|Rest], [Number1, Number2|Stack]) when Operator == "*" ->
  onp(Rest, [Number2 * Number1|Stack]);
onp([Operator|Rest], [Number1, Number2|Stack]) when Operator == "/" ->
  onp(Rest, [Number2 / Number1|Stack]);

onp([Operator|Rest], [Number|Stack]) when Operator == "sqrt" ->
  onp(Rest, [math:sqrt(Number)|Stack]);
onp([Operator|Rest], [Number1, Number2|Stack]) when Operator == "^" ->
  onp(Rest, [math:pow(Number2, Number1)|Stack]);
onp([Operator|Rest], [Number|Stack]) when Operator == "sin" ->
  onp(Rest, [math:sin(Number)|Stack]);
onp([Operator|Rest], [Number|Stack]) when Operator == "cos" ->
  onp(Rest, [math:cos(Number)|Stack]);
onp([Operator|Rest], [Number|Stack]) when Operator == "tan" ->
  onp(Rest, [math:tan(Number)|Stack]).

额外说明:原代码中二元运算符的操作数顺序错误——逆波兰表达式里,栈顶第一个元素是右操作数,第二个是左操作数,比如3 4 +需要计算3+4,原代码的Number1+Number2会得到4+3(结果碰巧一致,但减法、除法会出错),所以调整为Number2 + Number1才符合逻辑。

内容的提问来源于stack exchange,提问作者jon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 05:14:58