4

JavaCC 语法确实实现了可以解析这些行的语法:

[b]content[/b]
content[/b]
[b]content

尽管 JavaCC 解析器需要解析所有行,但它必须区分正确和不正确的标记行为。

正确的标签就像第一行一样,它们有一个打开和关闭标签。当标签匹配时,这将输出一个粗体格式的文本。

不正确的标签就像第 2 行和第 3 行一样,它们没有匹配的打开或关闭标签。当这些发生时,它们按原样写入输出,不会被解释为标签。

我已经尝试过下面的 JavaCC 代码(LOOKAHEAD = 999999)。问题是,这种语法总是将所有内容匹配为 invalidTag()而不是bold()。我如何确保 JavaCC 解析器尽可能匹配bold() ?

String parse() :
{}
{
    body() <EOF>
    { return buffer; }
}

void body() :
{}
{
    (content())*
}

void content() :
{}
{ 
    (text()|bold()|invalidTag)
}

void bold() :
{}
{
    { buffer += "<b>";  }
    <BOLDSTART>(content())*<BOLDEND>
    { buffer += "</b>"; }
}

void invalidTag() :
{
}
{
    <BOLDSTART> | <BOLDEND>
    { // todo: just output token
    }
}

TOKEN :
{
    <TEXT : (<LETTER>|<DIGIT>|<PUNCT>|<OTHER>)+ >
    |<BOLDSTART : "[b]" >
    |<BOLDEND : "[/b]" >

    |<LETTER : ["a"-"z","A"-"Z"] >
    |<DIGIT : ["0"-"9"] >
    |<PUNCT : [".", ":", ",", ";", "\t", "!", "?", " "] >
    |<OTHER : ["*", "'", "$", "|", "+", "(", ")", "{", "}", "/", "%", "_", "-", "\"", "#", "<", ">", "=", "&", "\\"]     >
}
4

2 回答 2

5

你的语法模棱两可。这可能不是您的错,因为为您要解决的问题生成明确的语法可能非常困难。

LL(k) 解析器可能不是这项工作的最佳工具。

但是,标记器可能很有用,并且使用堆栈来查找匹配和不匹配的标签对可能是合适的替代方案。

于 2010-10-06T22:15:59.260 回答
2

前段时间我了解到,一些琐碎的问题可以在语义或词汇层面很容易地解决,而在句法层面证明是非常困难或不可能的。

注意:我对 JavaCC 不太熟悉,但过去我使用过多个编译器生成器(我最喜欢的是 sablecc)。

您可能只需将您的“内容”定义为如下所示:

(text()|boldstart()|boldend()|invalidTag)

其中boldstart() 只会盲目地输出开始标签和boldend() - 一个结束标签。

但是,如果您想过滤所有这些并且只生成正确结束的标签,那么我建议为此制作某种有状态的自动机,为其提供开始和结束标签,注意(比如说)粗体是否应该开始、停止或继续(可能包括嵌套深度)并根据该输出开始,停止或无标签。与使用 JavaCC 中的语法或词法工具相比,这将非常容易实现。

于 2010-10-07T08:47:31.640 回答