1

我正在编写一个 ANTLR 语法来识别纯文本中的 HTML 块级元素。这是一个相关的片段,仅限于div标签:

grammar Test;

blockElement
  : div
  ;

div
  : '<' D I V HTML_ATTRIBUTES? '>' (blockElement | TEXT)* '</' D I V '>'
  ;

D : ('d' | 'D') ;
I : ('i' | 'I') ;
V : ('v' | 'V') ;

HTML_ATTRIBUTES
  : WS (~( '<' | '\n' | '\r' | '"' | '>' ))+
  ;

TEXT
  : (. | '\r' | '\n')
  ;

fragment WS
  : (' ' | '\t')
  ;

TEXT标记应该表示任何非块级元素,例如纯文本或内联标记(例如<b><\b>)。当我在嵌套块元素上测试它时,例如:

<div level_0><div level_1></div></div>

它正确解析它们。但是,只要我添加一些随机文本,它就会在消耗第一个TEXT令牌后立即抛出 MismatchedTokenException(0!=0),例如大写T

<div level_0>This is some random text</div>

有什么建议么?我在做一些概念上的错误吗?我正在使用 ANTLR v. 3.2 并使用 ANTLRWorks v. 1.4 进行测试。

谢谢

4

1 回答 1

3

我建议不要使用 ANTLRWorks 测试您的语法:错误消息很容易在控制台中丢失,因此它可能会按照您的预期解释您的测试输入。使用这样的自定义创建类来执行此操作:

import org.antlr.runtime.*;

public class Main {
    public static void main(String[] args) throws Exception {
        ANTLRStringStream in = new ANTLRStringStream("<div level_0>This is some random text</div>");
        TestLexer lexer = new TestLexer(in);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        TestParser parser = new TestParser(tokens);
        Sparser.parse());
    }
}

现在,以下规则不正确:

TEXT
  :  (. | '\r' | '\n')
  ;

.已经匹配\r和,\n所以它应该是:

TEXT
  :  .
  ;

更改时,您可以创建解析器和 lexter,编译所有 .java 文件并运行 Main 类:

java -cp antlr-3.2.jar org.antlr.Tool Test.g
javac -cp antlr-3.2.jar *.java
java -cp .:antlr-3.2.jar 主要

这将产生以下错误:

line 1:15 mismatched input 'i' expecting '</'

因为ifromThis正在被规则标记化I : ('i' | 'I') ;

您当前的方法存在更多问题:

  • HTML_ATTRIBUTES做的太多了:你应该有ATTRIBUTE,=VALUE规则,然后将复数(html属性)移动到你的解析器;
  • 现在你的属性不能包含<并且>不正确(可以包含它们,尽管不推荐)。

如果我是你,我会重新开始。如果你愿意,我愿意提出一个开始:就这么说吧。

于 2010-06-23T08:30:59.903 回答