Java 使用带有antlr4的jsp scriptlet解析脚本标记
我在使用antlr4解析包含scriptlet表达式的标记时遇到困难。我从现有的HTMLPasser和Lexer语法开始,并尝试根据需要进行修改。 解析器语法是:Java 使用带有antlr4的jsp scriptlet解析脚本标记,java,antlr4,jsp-tags,Java,Antlr4,Jsp Tags,我在使用antlr4解析包含scriptlet表达式的标记时遇到困难。我从现有的HTMLPasser和Lexer语法开始,并尝试根据需要进行修改。 解析器语法是: parser grammar HTMLParser; options { tokenVocab=HTMLLexer; } htmlDocument : script* ; script : SCRIPT_OPEN scriptAttribute* SCRIPT_TAG_CLOSE? WORD? SCRIP
parser grammar HTMLParser;
options { tokenVocab=HTMLLexer; }
htmlDocument
: script*
;
script
: SCRIPT_OPEN scriptAttribute* SCRIPT_TAG_CLOSE? WORD? SCRIPT_TAG_FULL_CLOSE
| SCRIPT_OPEN scriptAttribute* SCRIPT_TAG_SLASH_CLOSE
;
scriptAttribute
: scriptAttributeName SCRIPT_EQUALS QUOTE SCRIPLET_INSIDE_SCRIPT javaExpression SCRIPTLET_TAG_CLOSE scriptAttributeValue? QUOTE
| scriptAttributeName SCRIPT_EQUALS QUOTE scriptAttributeValue QUOTE
| scriptAttributeName
;
scriptAttributeName
: WORD
;
scriptAttributeValue
: SCRIPT_ATTRIBUTE
;
scriptlet
: SCRIPTLET_TAG_OPEN javaExpression SCRIPTLET_TAG_CLOSE
;
jspElementName
: TAG_NAME
;
jspElementAttribute
: jspAttributeName TAG_EQUALS jspAttributeValue
;
jspAttributeName
: TAG_NAME
;
jspAttributeValue
: ATTVALUE_VALUE
;
javaExpression
: VALID_JAVA_CHARS | SEA_WS*
;
词法语法:
lexer grammar HTMLLexer;
SCRIPT_OPEN
: '<script' ->pushMode(SCRIPT)
;
SCRIPTLET_TAG_OPEN
: ('<%!' | '<%=' | '<%') ->pushMode(SCRIPTVALUE)
;
SEA_WS
: (' '|'\t'|'\r'? '\n')+
;
TAG_NAME
: TAG_NameStartChar TAG_NameChar*
// | TAG_NameStartChar* ':' TAG_NameStartChar*
;
TAG_WHITESPACE
: [ \t\r\n] -> channel(HIDDEN)
;
fragment
HEXDIGIT
: [a-fA-F0-9]
;
fragment
DIGIT
: [0-9]
;
TAG_NameChar
: TAG_NameStartChar
// | ':'
| '-'
| '_'
| '.'
| DIGIT
| '\u00B7'
| '\u0300'..'\u036F'
| '\u203F'..'\u2040'
;
TAG_NameStartChar
: [a-zA-Z]
| '\u2070'..'\u218F'
| '\u2C00'..'\u2FEF'
| '\u3001'..'\uD7FF'
| '\uF900'..'\uFDCF'
| '\uFDF0'..'\uFFFD'
;
TAG_EQUALS
: '=' -> pushMode(ATTVALUE)
;
//
// attribute values
//
mode ATTVALUE;
// an attribute value may have spaces b/t the '=' and the value
ATTVALUE_VALUE
: [ ]* ATTRIBUTE -> popMode
;
ATTRIBUTE
: DOUBLE_QUOTE_STRING
| SINGLE_QUOTE_STRING
| ATTCHARS
| HEXCHARS
| DECCHARS
;
fragment ATTCHAR
: '-'
| '_'
| '.'
| '/'
| '+'
| ','
| '?'
| '='
| ':'
| ';'
| '#'
| [0-9a-zA-Z]
;
fragment ATTCHARS
: ATTCHAR+ ' '?
;
fragment HEXCHARS
: '#' [0-9a-fA-F]+
;
fragment DECCHARS
: [0-9]+ '%'?
;
fragment DOUBLE_QUOTE_STRING
: '"' ~[<"]* '"'
;
fragment SINGLE_QUOTE_STRING
: '\'' ~[<']* '\''
;
//
// <scripts>
//
mode SCRIPT;
SCRIPT_TAG_FULL_CLOSE
: '</script>' ->popMode
;
SCRIPT_TAG_CLOSE
: '>'
;
SCRIPT_TAG_SLASH_CLOSE
: '/>' -> popMode
;
SCRIPT_EQUALS
: '='
;
SCRIPLET_INSIDE_SCRIPT
: '<%' ->pushMode(SCRIPTVALUE)
;
SCRIPT_ATTRIBUTE
: SCRIPT_ATTCHARS
;
fragment SCRIPT_ATTCHARS
: SCRIPT_ATTCHAR+
;
SCRIPTTAG_WS
: [ \r\n\t]+ -> channel(HIDDEN)
;
WORD
: [a-zA-Z]+
;
QUOTE
: '"'
;
fragment SCRIPT_ATTCHAR
: '-'
| '_'
| '.'
| '/'
| ','
| ';'
| '\''
// | '"'
| [0-9a-zA-Z]
;
mode SCRIPTVALUE;
SCRIPTLET_TAG_CLOSE
: '%>' ->popMode
;
VALID_JAVA_CHARS
: SCRIPTCHARS+
;
SCRIPT_WS
: [\r\n\t]+ -> channel(HIDDEN)
;
fragment SCRIPTCHARS
: SCRIPTCHAR+ ' '?
;
fragment SCRIPTCHAR
: '-'
| '_'
| '.'
| '/'
| '+'
| ','
| '?'
| '='
| ':'
| ';'
| '#'
| '('
| ')'
| '}'
| '{'
| '@'
| '*'
| '!'
| '%'[0-9]+
| '&'
| '['
| ']'
| '~'
| '+'
| '^'
| '\r'
| '\t'
| '\n'
| ' '
| '"'
| '\''
| [0-9a-zA-Z]
;
lexer语法htmlexer;
脚本打开
: ''
;
脚本\u标记\u斜杠\u关闭
:“/>”->popMode
;
脚本_等于
: '='
;
SCRIPLET_内部_脚本
:''->popMode
;
有效的JAVA字符
:SCRIPTCHARS+
;
脚本
:[\r\n\t]+->频道(隐藏)
;
片段脚本字符
:SCRIPTCHAR+“”?
;
片段脚本字符
: '-'
| '_'
| '.'
| '/'
| '+'
| ','
| '?'
| '='
| ':'
| ';'
| '#'
| '('
| ')'
| '}'
| '{'
| '@'
| '*'
| '!'
| '%'[0-9]+
| '&'
| '['
| ']'
| '~'
| '+'
| '^'
|“\r”
|“\t”
|“\n”
| ' '
| '"'
| '\''
|[0-9a-zA-Z]
;
请注意:目前,我只是在一个不现实的简单两行文件上测试解析器,其中包含以下文本:
<script type="text/javascript" src="<%= request.getContextPath() %>"></script>
<script type="text/javascript" src="<%= request.getContextPath() %>/scripts/Main.js"></script>
输出为:
line 1:8 no viable alternative at input '<script type'
^<script^ start start index: 0 start stop index: 6
^<script^ start start index: 0 start stop index: 6
^
^ stop start index: 78 stop stop index: 79
^<script^ start start index: 80 start stop index: 86
^
第1:8行输入时没有可行的替代方案'