Java 使用带有antlr4的jsp scriptlet解析脚本标记

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

我在使用antlr4解析包含scriptlet表达式的标记时遇到困难。我从现有的HTMLPasser和Lexer语法开始,并尝试根据需要进行修改。 解析器语法是:

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行输入时没有可行的替代方案'