在计算器语法中为括号添加优先级

时间:2013-01-02 18:14:01

标签: functional-programming grammar sml smlnj parentheses

我正在用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   

1 个答案:

答案 0 :(得分: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,但我相信你能够解决这个问题......并填补空白。