HTML子集语法中的MismatchedTokenException

时间:2010-06-23 06:36:36

标签: antlr antlrworks

我正在编写一个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),e。 G。资本 T

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

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

谢谢

1 个答案:

答案 0 :(得分: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
  :  .
  ;

更改时,您可以创建解析器&amp; 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 Main

将产生以下错误:

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

因为来自i的{​​{1}}被This规则标记化。

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

  • I : ('i' | 'I') ;做得太多了:您应该使用HTML_ATTRIBUTESATTRIBUTE=规则,然后将复数(html属性)移到您的解析器中;
  • 现在您的属性不能包含VALUE<,这是不正确的(可以包含它们,但不建议这样做。)
如果我是你,我会重新开始。如果你愿意,我愿意提出一个开始:就这么说。