Parsing 试图将不匹配的括号设置为不正确的输入,不会';t在SML工作
我正在用SML写一个计算器 在我的程序中,我使用以下括号:Parsing 试图将不匹配的括号设置为不正确的输入,不会';t在SML工作,parsing,sml,smlnj,Parsing,Sml,Smlnj,我正在用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
{ } (* 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
和Lpar2
或Lpar
和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
我怎样才能解决这个问题 缩进有点不正确,但是当括号不匹配时,您已经得到的代码应该会引发
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
您的缩进有点不正确,但看起来您已经得到的代码应该在括号不匹配时引发
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
括号中不同的“优先级”有什么意义?括号中不同的“优先级”有什么意义?