我正在编写一个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进行测试。
谢谢
答案 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_ATTRIBUTES
,ATTRIBUTE
和=
规则,然后将复数(html属性)移到您的解析器中; VALUE
和<
,这是不正确的(可以包含它们,但不建议这样做。)