【问题标题】:lexing lisp in python在 python 中使用 lisp
【发布时间】:2022-10-24 17:08:04
【问题描述】:

那里!我对 lisp 语言很感兴趣,我决定创建自己的方言。这将是有史以来最简单的一个。

如您所知,lisp 中的所有内容都是一个列表(或至少是这种方言)。一个列表由一个命令组成,它出现在它的开头,也许参数是它们本身的列表。使用这些信息,我创建了以下内容。

class KList:
    def __init__(self, command, args=None):
        self.command = command
        self.args = args

所以使用这个结构(+ 1 2) 应该转向KList('+', [KList('1'), KList('2')]) & welp 来转换它,我需要一个词法分析器&我的问题是。我怎样才能转换它?有两件事对我很重要。

  1. 我只是有点讨厌为一个简单的项目下载数万亿个软件包。所以一个没有词法库的解决方案。
  2. Lisp 是一种函数式语言,它可能看起来很奇怪,但我使用 python 进行函数式编程,所以请避免使用语句和变异变量。

【问题讨论】:

    标签: python lisp


    【解决方案1】:

    一个简单的 Lisp 解析器可以很容易实现,基本上可以写一个递归下降自顶向下的解析器。 你有单独的阅读器,比如整数、字符串、符号的阅读器,无论你想要什么:

    class Reader:
    
        def read_integer(self, stream):
            pass
    
        def read_string(self, stream):
            pass
    
        def read_symbol(self, stream):
            pass
    
        def read_whitespace(self, stream):
            pass
    

    特别是复合形式的读者:

        def read_open_parenthesis(self, stream):
            # read as many forms as possible until
            # you reach ")"
            pass
    

    然后添加一个主阅读器,它可以查看流,检查正在读取哪些字符,并调用它需要的任何函数:

        def read_form(self, in):
            byte = stream.peek()
            if byte.isdigit():
                return self.read_integer(in)
            if byte == '(':
                return self.read_open_parenthesis(in)
            # etc.
    

    事实上,Common Lisp 阅读器就是这样做的,但是是以一种可编程的方式。有一个可读的将字符与阅读器功能相关联,您可以更改它可读的在运行时。例如,在您的情况下,如果下一个字符是数字,则调用 read-integer

    对于符号,您应该实习生它们在 Lisp 中,这意味着您在第一次解析符号时创建一个符号,然后在下次解析相同符号时使用相同的符号对象,因此符号是相同的。

    (eq 'a 'a)
    => T
    

    字符串不一定是这种情况:

    (eq "a" "a")
    => NIL
    

    (对于优化重复字符串的编译器来说,它可能是 T)

    从某种角度来看,这是一种非常简单的方法,但当然,Common Lisp 方法比这要复杂一些,一开始你可以忽略很多细微之处。有关更完整的说明,请参阅2.2 Reader Algorithm

    【讨论】:

    • 这很酷,但我实际上将数字和字符串本身作为命令包含在内。我不知道我在这里是否错了,但我想去扔一个 lex -> parse 阶段。你能不能自己解释一下算法,因为我不擅长阅读文档
    • 您如何将数字和字符串作为命令包含在内?!
    • 如果命令以“ & 以它结尾。它将是一个字符串。就像数字一样。如果它以 0-9 或 . & 以它们结尾。
    • 所以,你正在做我正在解释的事情,你正在根据你在源文件中看到的第一个字符解析不同类型的类型。这就是自顶向下解析背后的想法,我会在后面尝试更好地解释
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-22
    • 1970-01-01
    • 2014-09-03
    • 2015-05-13
    相关资源
    最近更新 更多