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语言解析器组合器库,除其他外,它还可以将EBNF和Regex嵌入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”。我认为您会发现这对您的项目确实很有用。最后但并非最不重要的,在图书馆的例子,有一个现成的程序,产生下的一个子集解析器;-)