2016-12-12 14 views
0

У меня есть следующий грамматик.Как обработать тег с пробелом в его значении с помощью antlr?

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:\/\[email protected]\-;\s*]+; 

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

Строка

<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> 

Я получаю следующее сообщение об ошибке:

ParseError extraneous input 'bar' expecting '</' clj-antlr.common/parse-error (common.clj:146) 

Проблема заключается в том, что пространство пропускается так, когда Foo bar имеет место, которое он дает ошибку , Но если я не пропущу пробел, я получаю еще одну ошибку в анализе META. (При пропуске пробелов не требуется S*).

ParseError extraneous input ' ' expecting {'>', NAME} 
mismatched input '>' expecting '><' 
mismatched input '<' expecting {<EOF>, COMMENT, S} clj-antlr.common/parse-error (common.clj:146) 

Вот мой лексемы файл, сгенерированный ANTLR:

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 я получаю следующее, но я не вижу каких-либо ошибок в знак сообщается. Это похоже на грамматику, которую я определил. Как я могу принимать пробелы в значениях тегов?

$ 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 

Спасибо.

ответ

1

Если вы поместили пробел между foo и bar, lexer произведет его как два токена (типа TEXT), но в грамматике указано, что разрешен только один токен. Для того, чтобы решить вашу проблему, то вы просто должны позволить несколько текстов в seqnece через плюс-оператор:

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

Также обратите внимание, что вы можете столкнуться с проблемами, как лексический будет конвертировать довольно много входов наименований и не в ТЕКСТы, поскольку они оба могут совпадать с шаблоном [A-Z0-9]+

+0

Я дал 'ТЕКСТ + ', но я получаю сообщение об ошибке:' ParseError посторонний вход' 'ожидает {' boring

+0

Как вы сказали, когда я даю' BOO 'как значение тега, он сопоставляется« NAME », поэтому я получаю сообщение об ошибке. Как я могу избежать этого? Я не хочу заменять 'NAME'' TEXT' так, чтобы он не соответствовал дополнительным символам. Возможно ли с помощью antlr? – boring

+0

Я исправил последнюю часть, дающую 'content' как значение и' content: NAME * | TEXT *; '. Но проблема с космосом не устранена. – boring

 Смежные вопросы

  • Нет связанных вопросов^_^