gpt4 book ai didi

在 Emacs Lisp 中解析

转载 作者:行者123 更新时间:2023-12-02 04:44:59 24 4
gpt4 key购买 nike

我正在 Emacs Lisp 中编写一个解析器。它是文本文件的解析器看起来像这样:

rule:
int: 1, 2, 3, ...
string: and, or, then, when
text:
----------
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Pellentesque
in tellus. In pharetra consequat augue. In congue. Curabitur
pellentesque iaculis eros. Proin magna odio, posuere sed, commodo nec,
varius nec, tortor.
----------
more: ...

rule:
...

我并不真正关心键(int,string,...)。我想要值(value)。因此,对于上面的文件,int 的值为“1,2,3,...”,string“and、or、then、when”和文本“Lorem ...”(不包括破折号)。

我正在考虑两种不同的解决方案,但不知道该使用哪一种。我应该:

  1. 创建一个简单的解析器,循环遍历所有行并为每个行将其与一些正则表达式匹配,然后将我想要的部分分组?

  2. 用词法分析器和解析器做一个更复杂的解析器?

现在文件非常简单,我想我不需要做与第二个选项一样先进的东西。但这些文件可能会被有点复杂,所以我想让它易于扩展。

你会如何解决这个问题?

最佳答案

您已经熟悉recursive descent parsers了吗? ?使用您最喜欢的编程语言(包括 Emacs Lisp)手动编写它们相对容易。对于非常简单的解析,通常可以使用 looking-at 来完成。和search-forward 。这些也将构成任何 tokenizing 的基础由递归下降解析器或任何其他类型的解析器调用的例程。

[2009 年 2 月 11 日] 我在下面的 emacs lisp 中添加了一个示例递归下降解析器。它解析简单的算术表达式,包括加法、减法、乘法、除法、求幂和带括号的子表达式。现在,它假设所有 token 都在全局变量 *tokens* 中,但是如果你修改gettokpeektok如有必要,您可以让他们穿过缓冲区。要按原样使用它,只需尝试以下操作:

(setq *token* '( 3 ^ 5 ^ 7 + 5 * 3 + 7 / 11))
(rdh/expr)
=> (+ (+ (^ 3 (^ 5 7)) (* 5 3)) (/ 7 11))

解析代码如下。

(defun gettok ()
(and *token* (pop *token*)))
(defun peektok ()
(and *token* (car *token*)))

(defun rdh/expr ()
(rdh/expr-tail (rdh/factor)))

(defun rdh/expr-tail (expr)
(let ((tok (peektok)))
(cond ((or (null tok)
(equal tok ")"))
expr)
((member tok '(+ -))
(gettok)
(let ((fac (rdh/factor)))
(rdh/expr-tail (list tok expr fac))))
(t (error "bad expr")))))

(defun rdh/factor ()
(rdh/factor-tail (rdh/term)))

(defun rdh/factor-tail (fac)
(let ((tok (peektok)))
(cond ((or (null tok)
(member tok '(")" + -)))
fac)
((member tok '(* /))
(gettok)
(let ((term (rdh/term)))
(rdh/factor-tail (list tok fac term))))
(t (error "bad factor")))))

(defun rdh/term ()
(let* ((prim (rdh/prim))
(tok (peektok)))
(cond ((or (null tok)
(member tok '(")" + - / *)))
prim)
((equal tok '^)
(gettok)
(list tok prim (rdh/term)))
(t (error "bad term")))))

(defun rdh/prim ()
(let ((tok (gettok)))
(cond ((numberp tok) tok)
((equal tok "(")
(let* ((expr (rdh/expr))
(tok (peektok)))
(if (not (equal tok ")"))
(error "bad parenthesized expr")
(gettok)
expr)))
(t (error "bad prim")))))

关于在 Emacs Lisp 中解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2228477/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com