4

我正在尝试学习如何使用 JavaCC 编写解析器。

我已经使用 JFlex 生成了一个词法分析器,它返回一个标记列表。每个令牌都是它自己的类。

我正在写生产规则,但例如,我不能写“;” 因为它不会接收分号,而是接收 TokenSemicolon 的实例?

我能做些什么?

此外,我对 TokenMangager 等感到困惑。我已经有一个词法分析器和我自己的兼容令牌类列表。这是什么?

请帮忙,因为我很困惑。

4

1 回答 1

3

你问了两个相关的问题:

“这是什么?” 我假设您的意思是:“什么是令牌管理器?”

令牌管理器是令牌对象的来源。每个 JavaCC 解析器都需要一个令牌源。顺便说一下,标记由 class 的对象表示Token。有两种方法可以制作令牌管理器。

  1. 让 JavaCC 为您生成一个。JavaCC 根据您放入.jj文件中的一组规则生成一个词法分析器。在这种方式下,它很像 JFlex。这是默认设置。
  2. 写你自己的。为此设置选项USER_TOKEN_MANAGER=true。然后 JavaCC 会生成一个 Java 接口,叫做TokenManager. 您需要做的就是用您自己的类实现该接口。当然,您应该使用该类的对象构造解析器。

“我能做些什么?”

有几种可能性。

  1. 在 JavaCC 中重写您的 JFlex 代码。然后,JavaCC 生成的令牌管理器将做与您的 JFlex 词法分析器基本相同的事情,但它将实现正确的接口并生成适当类型的令牌(即Token.)
  2. 编写一个适配器类。使用 JavaCC 的USER_TOKEN_MANAGER=true选项并编写一个适配器类来包装您的 JFlex 并实现TokenManager接口。
  3. 说服 JFlex 生成可与 JavaCC 一起使用的词法分析器。我不确定这是否可能,但如果是的话,它可能是最好的选择。在这种情况下,您将使用USER_TOKEN_MANAGER=true. 然后做一个类: class FooLexer extends FooJLexLexer implements TokenManager { ...put constructors here... }

对于选项 3,您必须确保生成的词法分析器实际上实现了TokenManager. 如果您真的需要所有自己的令牌类,您可以让它们扩展生成的Token类。

如果您使用选项 2,您构建解析器的代码可能看起来像这样

TokenManager tm = new AdaptJFlexLexerToJavaCC( jflexLexer ) ;
FooParser p = new FooParser( tm ) ;

选项 3 很想尝试。如果成功了,这可能是最简单的。

如果选项 3 不起作用,并且除非有令人信服的理由保留 JFlex 词法分析器,否则我会选择选项 1。从 JFlex 到 JavaCC 的转换可能在很大程度上是机械的,因此快速而简单。在 JFlex 中,JavaCC 唯一没有好的解决方案是A / B构造。

无论您采用哪种选择,请记住 JavaCC 希望每个选项Token都有一个.kind字段。这是一个整数,但您会在生成的 interface 中找到整数的符号名称FooConstants

于 2015-10-22T16:20:36.890 回答