在C中使用解析器组合器的更好方法?

Xia*_*Jia 6 c compiler-construction parsing parser-combinators

我正在尝试从头启动C(的子集),而不使用额外的依赖项(解析器生成器,库等)。我也想利用解析器组合器的思想,这在函数式编程中是一种很棒的技术。我想以一种简洁实用的方式将这种想法从功能世界借鉴到过程C中。

我尝试为以下玩具语法实现一些必要的解析器组合器,这也是Simon Peyton Jones 的《实现功能语言-教程》一书中的示例。

greeting -> hg person "!"
hg       -> "hello"
          | "goodbye"
Run Code Online (Sandbox Code Playgroud)

person以字母开头的令牌在哪里?例如,令牌列表

["goodbye", "James", "!"]
Run Code Online (Sandbox Code Playgroud)

被解析为

[(("goodbye", "James"), ["!"])]
Run Code Online (Sandbox Code Playgroud)

(这本书使用了Haskell,很难使它与语言无关,但是您会明白的:-)

我用C语言实现了这一点,您可以在这里查看代码:https : //gist.github.com/4451478

此实现花费200多行C代码,远远超过本书中编写的约20行Haskell。因此,我不确定我是否在使用C进行解析器组合器方面是否正确,以及是否有任何可能的改进。任何建议都欢迎。提前致谢。

小智 6

我本人正在研究这个主题,并且正在跟踪mpc的作者Daniel Holden的工作,mpc是一个编写良好的C语言解析器组合器库,除其他外,它还可以将EBNFRegex嵌入C代码中:

  mpc_parser_t *Expr  = mpc_new("expression");
  mpc_parser_t *Prod  = mpc_new("product");
  mpc_parser_t *Value = mpc_new("value");
  mpc_parser_t *Maths = mpc_new("maths");

  mpca_lang(MPCA_LANG_PREDICTIVE,
    " expression : <product> (('+' | '-') <product>)*; "
    " product : <value>   (('*' | '/')   <value>)*;    "
    " value : /[0-9]+/ | '(' <expression> ')';         "
    " maths : /^/ <expression> /$/;                    "
    Expr, Prod, Value, Maths, NULL);
Run Code Online (Sandbox Code Playgroud)

丹尼尔·霍尔登(Daniel Holden)也写了一本在线,向他展示了如何使用自己的图书馆写新语言是多么容易。这本书的标题是“建立自己的Lisp”。我认为您会发现这对您的项目确实很有用。最后但并非最不重要的,在图书馆的例子,有一个现成的程序,产生下的一个子集解析器;-)


Pro*_*ica 3

尝试Cesium3,它是 C 解析器组合器的实现。(LLVM。)