【问题标题】:Outline mode in EBNFEBNF 中的大纲模式
【发布时间】:2013-12-21 08:04:57
【问题描述】:

我正在尝试使用 instaparse 库为 org 模式文件编写解析器。该库采用 EBNF 表示法并将其转换为解析函数。 org-mode 文件使用以星开始的行来制作大纲标题,其中星数设置大纲树中的级别,像这样

* Headline
** Sub headline1
** Sub headline2

我的第一个尝试是将所有标题放在结果树中的同一级别:

(def outline
  (insta/parser
   "<S> = Headline-node *
    Headline-node =  Level <' '> Headline
    Level = #'^\\*+'
    Headline = #'\\S'+ <'\n'>"))
(outline "* Headline\n** Subheadline\n")
;=>
([:Headline-node [:Level "*"] [:Headline "H" "e" "a" "d" "l" "i" "n" "e"]] 
 [:Headline-node [:Level "**"] [:Headline "S" "u" "b" "h" "e" "a" "d" "l" "i" "n" "e"]])

也许我可以在之后转换树以将子标题放入标题中。但我更愿意从一开始就在标题中创建一个带有副标题的树。到目前为止,我唯一的想法是手动创建不同的关卡,如下所示:

(def outline
  (insta/parser
   "<S> = Headline-node1 *
    Headline-node1 =  <#'^\\* '> Headline (Headline-node2)*
    Headline-node2 =  <#'^\\*\\* '> Headline
    Headline = #'\\S'+ <'\n'>"))
(outline "* Headline\n** Subheadline\n")
;=>
([:Headline-node1 [:Headline "H" "e" "a" "d" "l" "i" "n" "e"] 
                  [:Headline-node2 [:Headline "S" "u" "b" "h" "e" "a" "d" "l" "i" "n" "e"]]])

但我想创建无限层次的标题。有没有办法在 EBNF 中传达这一点?

【问题讨论】:

  • 你在这个项目中走了多远?我只是想为 org-mode 文件编写一个 Instaparse 解析器,看来我必须自己编写 EBNF 规范,因为我找不到 org-mode 的规范。如果您已经开始,我很乐意以其他方式为您的项目或联合工作做出贡献。

标签: parsing clojure ebnf


【解决方案1】:

我认为这是不可能的。下推自动机可以准确识别上下文无关语言。但是想想下推自动机必须如何操作来决定您的示例中的标题级别。

下推自动机有一组有限的状态。因此,如果我们要允许任意深度的级别,它就不能使用状态来跟踪标题的级别。所以它必须使用它的堆栈。使用堆栈进行计数的唯一方法是每次读取* 时推送一个堆栈符号(也有有限数量的堆栈符号)。假设它位于某些*s 开头的输入字符串中的某个位置。它通过为每个* 推送一个堆栈符号来进行。但是当涉及到输入字符串中*s 的末尾时,自动机可以用来决定其动作的唯一内容是:输入字符串中的符号、它的状态以及堆栈上的顶部符号。我们“已经”知道输入符号不是*,所以这无济于事。我们知道堆栈的顶部是我们为每个* 推送一次的符号,所以这也无济于事。并且如前所述,状态集是有限的,因此我们不能以某种方式使用状态来计算堆栈上的符号数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-26
    • 2016-05-27
    • 2016-06-09
    • 1970-01-01
    • 1970-01-01
    • 2013-06-14
    • 2014-02-22
    • 1970-01-01
    相关资源
    最近更新 更多