1

我正在用 SML 写一个计算器。

在我的程序中,我使用以下括号:

{ }    (* highest priority *) 

[ ]    (* middle priority *) 

( )    (* weakest priority *) 

当用户输入一个字符串时,例如:

calc "1+(2*3)"   (* that's ok *) 

但是那些:

 calc "1+[2*3)"   (* Not Ok *) 

 calc "1+(2*3}"   (* Not Ok *) 

 calc "1+{2*3]"   (* Not Ok *) 

不是,因为左括号与右括号不匹配。

我试图用 SML 写,但它不起作用。当用户输入带有不平衡括号的表达式时,我想要做的是返回-1或显示错误消息

这是代码:

signature ScannerForExp = sig
  datatype token = 
                    (* parenthesis *)

                   Lpar3             (* { *)
                 | Rpar3             (* } *)
                 | Lpar2             (* [ *)
                 | Rpar2             (* ] *)  
                 | Lpar              (* ( *)
                 | Rpar              (* ) *)

                    (* operations *)

                 | Multiply          (* * *)
                 | Div               (* / *)
                 | Plus              (* + *)
                 | Minus             (* - *)
                 | Modulo            (* % *)
                 | Power             (* ^ *)                 
                 | Num of int        (* [0-9]+ *)
                 | Undef of string   (* undefined *)
  val scanner : string -> (token list)
end;



    | #"{"::r => if s = "" then (Lpar3,r) else (toToken s,c::l)
    | #"}"::r => if s = "" then (Rpar3,r) else (toToken s,c::l)     
    | #"["::r => if s = "" then (Lpar2,r) else (toToken s,c::l)
    | #"]"::r => if s = "" then (Rpar2,r) else (toToken s,c::l)
    | #"("::r => if s = "" then (Lpar,r) else (toToken s,c::l)
    | #")"::r => if s = "" then (Rpar,r) else (toToken s,c::l)

这是处理这个的函数:

 fun E l = E2 l
  and F l
      = case l of 
          (Num n)::l1 => (NumNode n,l1)
        | Lpar::l1 => let val (en,l2) = E l1  in case l2 of Rpar::l3 => (en,l3)


        | Lpar2::l1 => let val (en,l2) = E l1 in case l2 of Rpar2::l3 => (en,l3)


        | Lpar3::l1 => let val (en,l2) = E l1 in case l2 of Rpar3::l3 => (en,l3)



    ...
...
(* more code *)

但是当我尝试添加由LparwithLpar2Lparwith组成的规则时Lpar3

  fun E l = E2 l
  and F l
      = case l of 
          (Num n)::l1 => (NumNode n,l1)
        | Lpar::l1 => let val (en,l2) = E l1  in case l2 of Rpar::l3 => (en,l3)


        | Lpar2::l1 => let val (en,l2) = E l1 in case l2 of Rpar2::l3 => (en,l3)


        | Lpar3::l1 => let val (en,l2) = E l1 in case l2 of Rpar3::l3 => (en,l3)


        (* a ( with a ] *)
        | Lpar::l1 => let val (en,l2) = E l1  in case l2 of Rpar2::l3 => raise exception

我得到:

stdIn:5875.9-5903.34 Error: match redundant and nonexhaustive

我该如何解决?

4

1 回答 1

1

您的缩进有点偏离,但看起来您已经拥有的代码应该ParserForExp在括号不匹配时引发异常。

使用您的“新”代码,会发生错误,因为您有两种Lpar::l1情况,这使得其中一种是多余的。
我相信您需要移动不匹配的括号案例:

| Lpar::l1 => let val (en,l2) = E l1  in 
                    case l2 of Rpar::l3 => (en,l3)
                             | Rpar2::l3 => [raise mismatched parentheses]
                             | Rpar3::l3 => [raise mismatched parentheses]
                             | _ => raise ParserForExp 
                    end
于 2013-01-02T07:33:21.047 回答