如何在C++中将一个简单的类似 Lisp 的代码拆分为标记?

How to split a simple Lisp-like code to tokens in C++?

本文关键字:Lisp 代码 拆分 简单 一个 C++      更新时间:2023-10-16

基本上,该语言有 3 种列表和 3 种固定长度类型,其中一种是字符串。 使用正则表达式检测令牌的类型很简单,但将它们拆分为令牌并非易事。

字符串用双引号表示,双 qoute 用反斜杠转义。

编辑:

一些示例代码

{
print (sum (1 2 3 4))
if [( 2 + 3 ) < 6] : {print ("Smaller")}
}

列表类似

  • () 是仅在必要时计算的参数列表。
  • [] 是用更漂亮的方式表达 2 个操作数运算的特殊列表 道路。
  • {} 是始终计算的列表。第一个元素是一个函数 name,第二个是参数列表,这重复。
  • 任何 : 任何
  • [ : 任何 [: ...]] 转换为参数列表,这些参数列表具有由 :s 连接的元素。这仅用于使循环和条件看起来更好。

所有函数都采用单个参数。参数列表可用于需要更多参数的函数。您可以使用不同类型的 eval 函数来评估 fore 和参数列表。(每个列表模型都会有评估函数)

所以,如果你理解这一点,它的工作方式与 Lisp 非常相似,它只是有不同的列表类型来美化代码。

编辑: @rici

[[2 + 3] < 6]也可以。正如我所提到的,参数列表仅在必要时进行评估。由于<是一个需要长度为 2 的参数列表的函数,因此必须以某种方式计算(2 + 3),它[(2 + 3) < 6]的其他方式将转换为< (2 + 3) : 6等于< (2 + 3 6)哪个是和无效的参数列表<。但我看到你的观点,在这种情况下,自动解析应该如何工作并非易事。我上面描述的版本是,[...]使用类似eval_as_oplist (...)的函数计算参数列表 但我想你是对的,因为这样,你就不能在[...]内以常规方式使用参数列表,即使你没有理由这样做,这也是有问题的, 因为它不会带来更好的代码。所以[[. . .] . .]是一个更好的代码,我同意。

与其发明自己的"类似Lisp但更简单"的语言,不如考虑使用现有的Lisp(或Scheme)实现并将其嵌入到C++应用程序中。

虽然设计你自己的语言,然后为它编写自己的解析器和解释器肯定很有趣,但你很难想出比Scheme更好的设计,更强大,更有效和更健壮的实现,它的众多实现。

赤壁方案:http://code.google.com/p/chibi-scheme/特别适合嵌入C/C++代码,它非常小,速度很快。

我建议使用Flex(可能与Bison一起使用)或ANTLR,它具有C++输出目标。

由于谷歌比在我自己的文件服务器上查找内容更简单,因此以下是其他人的示例:

http://ragnermagalhaes.blogspot.com/2007/08/bison-lisp-grammar.html

此示例存在格式问题(可以通过在文本编辑器中查看 HTML 来解决),并且仅支持一种类型的列表,但它应该可以帮助您入门,并且肯定会显示如何将项目拆分为标记。

我相信Boost.Spirit适合这项任务,前提是您可以为您提出的语言构建与PEG兼容的语法。从例子中看不出情况是否如此。

更具体地说,Spirit有一个叫做utree的通用AST,并且有将符号表达式(即lisp语法)解析为utree的示例代码。

你不必使用utree来利用Spirit的解析和词法功能,但你必须有自己的AST表示。也许这就是你想要的?