Plai 2: Everything about parser

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

  

 

转载于:https://www.cnblogs.com/memo-store/p/5987445.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值