如何从JavaCC源生成Python解析器?

1 投票
2 回答
1840 浏览
提问于 2025-04-16 04:17

我说的标题中的???是因为我不太确定。让我来解释一下我的情况。

我不是计算机科学的学生,也没有上过编译器的课程。直到现在,我一直认为编译器的开发者或者上过编译器课程的学生非常了不起,因为他们需要用自己写编译器的语言来编写编译器的解析器部分。这可不是一件简单的事情,对吧?

我正在处理信息检索的问题。我想用的编程语言是Python。

解析器的性质: http://ir.iit.edu/~dagr/frDocs/fr940104.0.txt是一个示例文档集。这个文件包含大约50个文档,还有一些类似XML的标记。(你可以在上面的链接中看到)。我需要记录一些其他的值,比如<DOCNO> FR940104-2-00001 </DOCNO><PARENT> FR940104-2-00001 </PARENT>,而且我只需要索引<TEXT> </TEXT>部分的内容,这部分包含一些我需要去掉的多余标签,还有很多<!-- -->注释需要忽略,以及一些&hyph; &space; &amp;字符实体。我不知道为什么这个文档集会有这些东西,因为它显然既不是为了在浏览器中显示,也不是一个合格的XML文档。

我考虑使用Python的XML解析器来提取所需的文本。但经过一些搜索,我发现了JavaCC解析器的源代码(Parser.jj),这是我正在使用的同一个文档集在这里。快速查阅JavaCC编译器生成器后,我发现编译器的开发者并没有我想象的那么厉害。他们使用编译器生成器来生成所需语言的解析器代码。维基百科上说,编译器生成器的输入是语法(通常是BNF)。这让我感到困惑。

  1. Parser.jj是编译器生成器JavaCC的语法吗?它显然不是BNF。这种语法叫什么?为什么这个语法是Java语言的?难道没有一种通用的语法语言吗?
  2. 我想要一个Python解析器来解析这个文档集。有办法把Parser.jj转换成Python的等价物吗?如果可以,那是什么?如果不可以,我还有什么其他选择?
  3. 有没有人知道这个文档集是什么?它的原始来源在哪里?我想看看一些描述。它在互联网上以frDocs.tar.gz的名字分发。

2 个回答

1

你不能仅仅通过一个(E)BNF语法来构建一个解析器,更不用说整个编译器了。这个语法只是描述了语法规则,也就是代码的结构(有些语法,比如Python的缩进规则,是根本无法用这种方式表示的),而没有涉及到语义。你要么使用不同的工具来处理这些方面,要么使用更高级的框架(比如C++的Boost::Spirit或者Haskell的Parsec),它们可以把这两者结合起来。

JavaCC(就像yacc一样)负责生成一个解析器,也就是一个可以理解从源代码中读取的符号的子程序。为此,它们将一种类似(E)BNF的表示法和用生成的解析器所用的语言(比如Java)编写的代码混合在一起,以便构建解析树。当然,你可以创造一种新的语言,但因为现有的语言已经能很好地处理这些任务,所以这样做没有太大意义。而且编译器的其他部分可能也是用同一种语言手动编写的,所以把“我得到了符号,我该怎么处理它们?”这一部分留给将要编写这些其他部分的人是有道理的;)

我从来没有听说过“PythonCC”,谷歌也没有找到相关信息(其实在谷歌代码上有一个“pythoncc”项目,但它的描述只是说“pythoncc是一个试图为Python脚本生成优化机器代码的程序。”而且自三月份以来没有更新)。你是指这些Python解析库/工具吗?不过我觉得没有办法自动将JavaCC的代码转换为Python的等价代码,但整个过程看起来相对简单,所以如果你深入学习一下通过JavaCC和你选择的[Python库/工具]进行解析,你可能能够自己翻译过来……

2

为什么你称这个为“XML风格”的标记?对我来说,这看起来像是很标准的基本XML。你可以试试elementTree或者lxml。与其自己写一个解析器,不如使用那些已经存在的、稳定且经过充分测试的库。

撰写回答