3

私はSMLで簡単な電卓を書いて​​います、そして私のコードは3種類の括弧をサポートする必要があります:

( ) 

[ ] 

{ } 

中のどこに、表現{ }が現れることができます、{ } , [ ] , ( )

中に、表現[ ]を表示することができます、[ ] , ( )

そして、中( )には、式だけを表示することができます( )

意味は、{ }最高の優先度、[ ]-中間の優先度、( )最低の優先度です。

それを達成するための最良のアプローチは何でしょうか?

別々のケースで実行されるループと再帰が多すぎる大きなメソッドを作成しましたが、これが最善のアプローチではないと思います。

任意の提案をいただければ幸いです

よろしく

編集 :

関連するコード:

signature CalculatorOperation = sig
  datatype token = 
                    (* paranthesis *)

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

構造 :

structure CalculatorOperation : CalculatorOperation = struct 
  datatype token =
                    (* paranthesis *)

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

スキャナー:

 fun stringScanner s [] = (toToken s,[])
    | stringScanner s (c::l)
      = case c::l of
          #" "::r => if s = "" then (stringScanner "" l) else (toToken s,l)
        (* paranthesis *)

        | #"{"::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)

パーサー:

structure CalculatorParser : CalculatorParser = struct
  open CalculatorOperation

  exception CalculatorParser

  datatype expr = NumNode of int
               | UminusNode of expr
               | MultiplyNode of expr * expr
               | DivNode of expr * expr
               | PlusNode of expr * expr
               | MinusNode of expr * expr
               | ModuloNode of expr * expr
               | PowerNode of expr * expr                          





  fun parserBrackets l = parserHelper2 l
  and parserHelper l
      = case l of 
          (Num n)::l1 => (NumNode n,l1)
        | Lpar3::l1 => let val (en,l2) = parserBrackets l1  in case l2 of Rpar3::l3 => (en,l3)
        | _ => raise CalculatorParser end

        | Lpar2::l1 => let val (en,l2) = parserBrackets l1 in case l2 of Rpar2::l3 => (en,l3)
        | _ => raise CalculatorParser end   

        | Lpar::l1 => let val (en,l2) = parserBrackets l1 in case l2 of Rpar::l3 => (en,l3)
        | _ => raise CalculatorParser end   
4

1 に答える 1

2

私はSMLの専門家ではありませんが、あなたの説明から、あなたが探している構文規則はBNFで次のように表現できることがわかります。

<expr1> ::= '{' ( <expr1> | <expr2> ) '}'

<expr2> ::= '[' ( <expr2> | <expr3> ) ']'

<expr3> ::= '(' ( <expr3> | <expr> ) ')' 

データ型exprの定義を見ると、expr1、expr2、およびexpr3に同様の型を次のように定義できるように思われます。

datatype expr3 = E3Node of expr3
              | ENode of expr

datatype expr2 = E2Node of expr2
              | E3Node of expr3

datatype expr1 = E1Node of expr1
              | E2Node of expr2

正直なところ、これが有効なSMLであるかどうかさえわかりませんが、それを修正してギャップを埋めることができると確信しています。

于 2013-01-05T23:01:22.823 に答える