标签:res list let else err 表达式 isp symbol error
plai-type 的parser, 不得不说lisp语言还是擅长处理括号表达式,而且其list 的member允许类型不同,但是说真的,还是不怎么喜欢lisp。
#lang plai-typed
(define-type ArithC
[numC (n : number)]
[plusC (l : ArithC) (r : ArithC)]
[multC (l : ArithC) (r : ArithC)])
(define (parse [s : s-expression]) : ArithC
(cond
[(s-exp-number? s) (numC (s-exp->number s))]
[(s-exp-list? s)
(let ([sl (s-exp->list s)])
(case (s-exp->symbol (first sl))
[(+) (plusC (parse (second sl)) (parse (third sl)))]
[(*) (multC (parse (second sl)) (parse (third sl)))]
[else (error ‘parse "invalid list input")]))]
[else (error ‘parse "invalid input")]))
(parse ‘(+ (* 1 2) (+ 2 3)))
因为刚开始学OCaml, 所以也用OCaml写了一个parser,但是我是用状态机实现的,很ugly, verbose,而且感觉代码风格还是imperative的,离functional 还是有很大的距离。
let s = "(+ (* 1 2) (+ 2 3))" in
let l = String.length s in
let state : int ref = ref 0 in
let rec parse (i : int) =
if i >= l then ()
else (
match s.[i] with
| ‘(‘ ->
print_char ‘(‘;
if !state = 0 then (
state := 1;
parse (i+1);
)
else if !state = 3 || !state = 5 then (
state := 1;
parse (i+1);
)
else (
print_string "error";
parse (i+1);
)
| ‘+‘ ->
if !state = 1 then (
print_string "plusC";
state := 2;
parse (i+1);
)
else (
print_string "error";
parse (i+1);
)
| ‘*‘ ->
if !state = 1 then (
print_string "multC";
state := 2;
parse (i+1);
)
else (
print_string "error";
parse (i+1);
)
| ‘ ‘ ->
print_char ‘ ‘;
if !state = 2 then (
state := 3;
parse (i+1);
)
else if !state = 4 || !state = 7 then (
state := 5;
parse (i+1);
)
else (
print_string "error";
parse (i+1);
)
| ‘)‘ ->
print_char ‘)‘;
if !state = 7 then (
state := 7;
parse (i+1);
)
else if !state = 6 then (
state := 7;
parse (i+1);
)
else (
print_string "error";
parse (i+1);
)
| c ->
Printf.printf "(numC %c)" c;
if !state = 3 then (
state := 4;
parse (i+1);
)
else if !state = 1 then (
state := 8;
parse (i+1);
)
else if !state = 5 then (
state := 6;
parse (i+1);
)
else (
print_string "error";
parse (i+1);
)
)
in parse 0
Plai 2: Everything about parser
标签:res list let else err 表达式 isp symbol error
原文地址:http://www.cnblogs.com/memo-store/p/5987445.html