首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用antlr解析带有空格的标记?

如何使用antlr解析带有空格的标记?
EN

Stack Overflow用户
提问于 2016-12-12 07:49:09
回答 1查看 390关注 0票数 0

我有下面的语法。

代码语言:javascript
复制
meta 
    : '<' NAME '>' TEXT '</' NAME '>'
    | '<' NAME S* attribute* '>';

dl : '<' NAME '><' TEXT '>' dt* '</' NAME '><' TEXT '>';

dt : '<' NAME '><' NAME S* attribute* S* '>' TEXT '</' NAME '>';

attribute : attributeName '=' attributeValue;

attributeName : NAME;

attributeValue : VAL;

NAME : [A-Z0-9_-]+;

VAL : '"'.*?'"';

TEXT : [A-Za-z0-9:\/\.@\-;\s*]+;

S : [ \t\r\n]+ -> skip;

字符串是

代码语言:javascript
复制
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<TITLE>Abcd</TITLE>
<H1>Abcd</H1>
<DL><p>
    <DT><H3 ADD_DATE="1481473849" LAST_MODIFIED="1481473992" PERSONAL_XYZ_FOLDER="true">Foo bar</H3>
</DL><p>

我得到了以下错误:

代码语言:javascript
复制
ParseError extraneous input 'bar' expecting '</'  clj-antlr.common/parse-error (common.clj:146)

问题是空间被跳过了,所以当Foo bar有一个空格时,它就会产生一个错误。但是,如果我不跳过这个空间,那么在META解析中就会出现另一个错误。(跳过空格时不需要S* )。

代码语言:javascript
复制
ParseError extraneous input ' ' expecting {'>', NAME}
mismatched input '>' expecting '><'
mismatched input '<' expecting {<EOF>, COMMENT, S}  clj-antlr.common/parse-error (common.clj:146)

以下是由antlr生成的令牌文件:

代码语言:javascript
复制
T__0=1
T__1=2
T__2=3
T__3=4
T__4=5
DTD=6
COMMENT=7
NAME=8
VAL=9
TEXT=10
S=11
'<'=1
'>'=2
'</'=3
'><'=4
'='=5

当我使用grun运行时,我会得到以下内容,但是在报告的令牌中没有看到任何错误。它类似于我定义的语法。如何接受标记值中的空格?

代码语言:javascript
复制
$ grun MyGrammer r -tokens
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
[@0,0:0='<',<1>,1:0]
[@1,1:4='META',<8>,1:1]
[@2,5:5=' ',<11>,1:5]
[@3,6:15='HTTP-EQUIV',<8>,1:6]
[@4,16:16='=',<5>,1:16]
[@5,17:30='"Content-Type"',<9>,1:17]
[@6,31:31=' ',<11>,1:31]
[@7,32:38='CONTENT',<8>,1:32]
[@8,39:39='=',<5>,1:39]
[@9,40:65='"text/html; charset=UTF-8"',<9>,1:40]
[@10,66:66='>',<2>,1:66]
[@11,67:67='\n',<11>,1:67]
[@12,68:67='<EOF>',<-1>,2:0]
No method for rule r or it has arguments

谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-12-12 09:04:06

如果在foobar之间放置一个空格,则lexer会将其生成为两个标记(类型为TEXT),但语法声明只允许使用一个名称标记。为了解决您的问题,您只需通过加号运算符在seqnece中允许一些文本:

代码语言:javascript
复制
dt : '<' NAME '><' NAME S* attribute* S* '>' TEXT+ '</' NAME '>';

还请注意,您可能会遇到问题,因为Lexer将转换相当多的名字输入,而不是文本输入,因为它们都可以与模式[A-Z0-9]+相匹配。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41096268

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档