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

  

时间: 2024-08-25 00:39:52

Plai 2: Everything about parser的相关文章

FFmpeg的HEVC解码器源代码简单分析:解析器(Parser)部分

上篇文章概述了FFmpeg中HEVC(H.265)解码器的结构:从这篇文章开始,具体研究HEVC解码器的源代码.本文分析HEVC解码器中解析器(Parser)部分的源代码.这部分的代码用于分割HEVC的NALU,并且解析SPS.PPS.SEI等信息.解析HEVC码流(对应AVCodecParser结构体中的函数)和解码HEVC码流(对应AVCodec结构体中的函数)的时候都会调用该部分的代码完成相应的功能. 函数调用关系图 FFmpeg HEVC解析器(Parser)部分在整个HEVC解码器中的

Python html.parser库学习小结

分类路径:/Datazen/DataMining/Crawler/ 前段时间,一朋友让我做个小脚本,抓一下某C2C商城上竞争对手的销售/价格数据,好让他可以实时调整自己的营销策略.自己之前也有过写爬虫抓某宝数据的经历,实现的问题不大,于是就答应了.初步想法是利用pyhton中的urllib.request和re两个lib(本文示例用的是Pyhton 3.4 ,2.x的请自行切换),外加上其他的统计分析功能的话,最多两个晚上(白天要工作)可以搞定.实际上做的过程中,遇到了两个主要困难: (1)电商

Stanford Parser 详细使用

http://blog.csdn.net/pipisorry/article/details/42976457 stanford-parser的使用 1.到斯坦福官方网站http://nlp.stanford.edu/software/lex-parser.shtml下载软件包,解压. 2.在eclipse中新建一个java project,把解压得到根目录下的stanford-parser.jar和stanford-parser-3.*.*-models.jar两个包导入项目到项目引用包中,

IIS 日志分析工具:Log Parser Studio

1.安装Log Parser,下载地址:http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=24659 2.安装Log Parser Studio,下载地址:http://gallery.technet.microsoft.com/Log-Parser-Studio-cd458765,下载之后解压即可. 3. 运行Log Parser Studio:在解压的LPSV2.D1文件夹中运行LPS.exe

极其简便的PHP HTML DOM解析器PHP Simple HTML DOM Parser/有中文手册

极其简便的PHP HTML DOM解析器PHP Simple HTML DOM Parser,有中文手册,对于需要分析HTML代码dom结构的php开发者来说,是一个极其有用的函数库,使用Jquery风格的dom节点查找语法,强烈推荐. 下面是其"快速入门",从中文手册里节选而来 //从一个URL或者文件创建一个DOM对象$html = file_get_html('http://www.google.cn/'); // 寻找所有的img标签foreach($html->find

[LeetCode] Mini Parser 迷你解析器

Given a nested list of integers represented as a string, implement a parser to deserialize it. Each element is either an integer, or a list -- whose elements may also be integers or other lists. Note: You may assume that the string is well-formed: St

Log Parser 2.2 + Log Parser Lizard GUI 分析IIS日志示例

Log Parser 日志分析工具,用命令行操作,可以分析 IIS logs,event logs,active directory,log4net,file system,t-sql Log Parser Lizard 以可视化界面操作,使用类似sql的语法查询 下载地址: Log Parser 2.2 :http://www.microsoft.com/en-us/download/details.aspx?id=24659 Log Parser Lizard GUI :http://www

介绍一个简单的Parser

我们已经学习了怎样创建一个简单的Monad, MaybeMonad, 并且知道了它如何通过在 Bind函数里封装处理空值的逻辑来移除样板式代码. 正如之前所说的,我们可以在Bind函数中封装更复杂的逻辑. 下面给出一个更复杂更典型的Monad例子,一个解析器Monad. 在本篇将要介绍一个解析器,在之后的篇幅里将会把解析器转换成一个 Monad. 首先我们思考解析器要完成什么功能,它接受一个输入,通常是一些文本,然后输出期望的结果. 因此一个CSV解析器将会接受一个文本文件,输出行和列的数据,并

将我们的parser转换成Monad

还记得我们上一篇delegate类型的parser吗 ,在开始本篇之前,强烈建议你复习一下这个parser定义 public delegate Maybe<Tuple<T,string>>Parser<T>(string input) 还记得我们组合这些parser的不易吗?现在我们采用新的方式将parser转换为Monad, 我们已经知道了如何将泛型类和泛型接口转换成Monad, 同样的也可以将委托转换成Monad 首先我们实现一个ToParser方法, 它相当简单,