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 *)

Lparしかし、 withLpar2または Lparwithで構成されるルールを追加しようとすると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、括弧が一致しない場合は、すでに取得しているコードで例外が発生するようです。

「新しい」コードでは、2つのLpar::l1ケースがあり、そのうちの1つが冗長になるため、エラーが発生します。
不一致の括弧の場合を移動する必要があると思います。

| 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 に答える