【问题标题】:Writing a formal language parser with Lisp用 Lisp 写一个正式的语言解析器
【发布时间】:2014-02-06 18:46:31
【问题描述】:

我的公司正在设计一种新的领域特定脚本语言;我必须实现一个解析器,将我们全新的编程语言翻译成通用脚本语言,以便能够执行它。

我这样做的通常方法是使用BisonFlex 工具生成翻译器的C/C++ 代码。

我找到了其他工具,适用于大多数主流编程语言,但没有找到适用于 Lisp 的工具。

Lisp 没有被用过吗?用Lisp编写解析器的常用方法是什么?

注意:对我来说,任何可以提供帮助的Lisp 实现/方言都可以,我没有任何偏好。

【问题讨论】:

  • 查看Clojure Toolbox 的解析部分,了解该方言的一些选项。

标签: scheme lisp racket formal-languages


【解决方案1】:

覆盖Racket 部分:

人们经常编写解析器,有很多方法可以这样做:

  • 手动编写递归下降解析器。
  • 在 Racket 中使用 parser-tools 库,它是 lex/yacc 样式。
  • 使用 Ragg,一个 AST 生成器生成器,让您编写 BNF。
  • 使用Parsack,一个类似于 Haskell 的 Parsec 的单子解析器组合库。
  • 我可能忽略了至少六个其他选项(例如,我知道至少有一个用于 Racket 的 PEG 样式库)。

【讨论】:

  • 如果 DSL 是基于 S 表达式的,您可以只使用 read (如果需要,还可以使用宏扩展)。 ;-)
  • Matthew Flatt 在 ACM Queue 中也有一篇相关文章,是关于在 Racket 中使用自己的语法从零到 mini-DSL:queue.acm.org/detail.cfm?id=2068896
  • Lisp 宏可以解析非 lispy 语法吗?就像想象在 Lisp 中解析 Haskell 一样的语法?
  • @CMCDragonkai,不,但上面提到的解析器工具的唯一目的是将非 lispy 语法转换为 lispy 语法。以下是 bf 的示例:github.com/expede/fainbracket
【解决方案2】:

嗯,在 Common Lisp 中执行此操作的“通常”方式是……在 Lisp 中执行此操作。

许多特定领域的语言(众所周知,Lisp 专门为此目的专门化了!)只是使用宏工具将其编写为 Lisp 本身的扩展。好处是,编写 DSL 很简单。缺点是,它们往往“看起来像”lisp。

Common Lisp 标准中 DSL 的一些示例包括 LOOP 宏自己的子语言和 FORMAT 说明符的子语言。

由于 Lisp 的 s-expression 符号名义上是抽象语法树的一种书面形式,它是避免使用大量自己的词法分析器或解析器的一种方法;你可以使用READ

话虽如此,您可以使用一些常见的包,这些包可能在GRAYLEXCL-LEXER 等中找到;查看与您的语法相似的其他语言的解析器可能会有所帮助。在 Quicklisp 中,我看到:

CL-USER> (ql:system-apropos "parse")
#<SYSTEM cl-arff-parser / cl-arff-parser-20130421-git / quicklisp 2013-08-13>                                                                                                                                                                                                   
#<SYSTEM cl-date-time-parser / cl-date-time-parser-20130813-git / quicklisp 2013-08-13>                                                                                                                                                                                         
#<SYSTEM cl-html-parse / cl-html-parse-20130813-git / quicklisp 2013-08-13>                                                                                                                                                                                                     
#<SYSTEM cl-html5-parser / cl-html5-parser-20130615-git / quicklisp 2013-08-13>                                                                                                                                                                                                 
#<SYSTEM cl-html5-parser-tests / cl-html5-parser-20130615-git / quicklisp 2013-08-13>                                                                                                                                                                                           
#<SYSTEM cl-pdf-parser / cl-pdf-20130420-git / quicklisp 2013-08-13>                                                                                                                                                                                                            
#<SYSTEM cli-parser / cl-cli-parser-20120305-cvs / quicklisp 2013-08-13>                                                                                                                                                                                                        
#<SYSTEM clpython.parser / clpython-20130615-git / quicklisp 2013-08-13>                                                                                                                                                                                                        
#<SYSTEM com.gigamonkeys.parser / monkeylib-parser-20120208-git / quicklisp 2013-08-13>                                                                                                                                                                                         
#<SYSTEM com.informatimago.common-lisp.html-parser / com.informatimago-20130813-git / quicklisp 2013-08-13>                                                                                                                                                                     
#<SYSTEM com.informatimago.common-lisp.parser / com.informatimago-20130813-git / quicklisp 2013-08-13>                                                                                                                                                                          
#<SYSTEM csv-parser / csv-parser-20111001-git / quicklisp 2013-08-13>                                                                                                                                                                                                           
#<SYSTEM fucc-parser / fucc_0.2.1 / quicklisp 2013-08-13>                                                                                                                                                                                                                       
#<SYSTEM http-parse / http-parse-20130615-git / quicklisp 2013-08-13>                                                                                                                                                                                                           
#<SYSTEM http-parse-test / http-parse-20130615-git / quicklisp 2013-08-13>                                                                                                                                                                                                      
#<SYSTEM js-parser / js-parser-20120909-git / quicklisp 2013-08-13>                                                                                                                                                                                                             
#<SYSTEM parse-declarations-1.0 / parse-declarations-20101006-darcs / quicklisp 2013-08-13>                                                                                                                                                                                     
#<SYSTEM parse-float / parse-float-20121125-git / quicklisp 2013-08-13>                                                                                                                                                                                                         
#<SYSTEM parse-float-tests / parse-float-20121125-git / quicklisp 2013-08-13>                                                                                                                                                                                                   
#<SYSTEM parse-js / parse-js-20120305-git / quicklisp 2013-08-13>                                                                                                                                                                                                               
#<SYSTEM parse-number / parse-number-1.3 / quicklisp 2013-08-13>                                                                                                                                                                                                                
#<SYSTEM parse-number-range / parse-number-range-1.0 / quicklisp 2013-08-13>                                                                                                                                                                                                    
#<SYSTEM parse-number-tests / parse-number-1.3 / quicklisp 2013-08-13>                                                                                                                                                                                                          
#<SYSTEM parse-rgb / cl-tcod-20130615-hg / quicklisp 2013-08-13>                                                                                                                                                                                                                
#<SYSTEM parseltongue / parseltongue-20130312-git / quicklisp 2013-08-13>                                                                                                                                                                                                       
#<SYSTEM parser-combinators / cl-parser-combinators-20121125-git / quicklisp 2013-08-13>                                                                                                                                                                                        
#<SYSTEM parser-combinators-cl-ppcre / cl-parser-combinators-20121125-git / quicklisp 2013-08-13>                                                                                                                                                                               
#<SYSTEM parser-combinators-tests / cl-parser-combinators-20121125-git / quicklisp 2013-08-13>                                                                                                                                                                                  
#<SYSTEM py-configparser / py-configparser-20101006-svn / quicklisp 2013-08-13>                                   

【讨论】:

  • 正如programmers.stackexchange.com/a/163246/41788 最雄辩地指出的那样……“是的,Lisp 是一种元语言。使用它的最佳方式是为特定领域的语言实现编译器。 Lisp 中的每个小宏本质上都是一个编译器。”
【解决方案3】:

在 common-lisp 中有两种解析非 lispy 语言的方法。

1) 使用可读表。这是经典的方式:lisp 阅读器算法已经是一个简单的递归体面解析器,它支持基于字符的调度。 Vacietis 这样做here

2) 使用解析库。我可以推荐 esrap 作为进行 Packrat 解析的好工具,而 smug 作为进行 monadic 解析的好工具。两者都在 quicklisp 中可用

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-12
    • 1970-01-01
    • 2018-10-23
    • 1970-01-01
    • 2018-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多