如何在C++中将一个简单的类似 Lisp 的代码拆分为标记?
How to split a simple Lisp-like code to tokens in C++?
基本上,该语言有 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表示。也许这就是你想要的?
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 代码在main()中运行,但在函数中出现错误
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 编译包含字符串的代码时遇到问题
- 我在c++代码中生成了一个运行时#3异常
- 如何在linux终端中同时编译和运行c++代码
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 在Linux for Windows上编译C++代码时出错
- 我的字符计数代码计算错误.为什么
- 孤立代码块在结构中引发异常
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 此代码是否违反一个定义规则
- 为什么我的代码在输出中增加了93天
- 我的简单if-else语句是如何无法访问的代码
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 如何在C++中将一个简单的类似 Lisp 的代码拆分为标记?
- RPC从C++代码到公共Lisp代码
- 如何将这个lisp函数转换为可编译代码