2017-06-06 6 views
0

Ich möchte JSP-Dateien zu identifizieren, um die Richtlinie Tags, Jsp Aktionselemente, Scriptlet Ausdruck etc. zu identifizieren. Dafür versuche ich, die vorhandene HTML-Code grammar zu erweitern. Ich habe Probleme mit der Unterscheidung von normalen HTML-Tags und JSP-Tags. Die bestehende Grammatik hat die folgenden Lexer Regeln:Antlr4 Parsing Jsp Scriptlets Ausdruck Direktive

TAG_OPEN 
    : '<' -> pushMode(TAG) 
    ; 
// 
// tag declarations 
// 
mode TAG; 

TAG_CLOSE 
    : '>' -> popMode 
    ; 

TAG_SLASH_CLOSE 
    : '/>' -> popMode 
    ; 

TAG_SLASH 
    : '/' 
    ; 

// 
// lexing mode for attribute values 
// 
TAG_EQUALS 
    : '=' -> pushMode(ATTVALUE) 
    ; 

TAG_NAME 
    : TAG_NameStartChar TAG_NameChar* 
    | TAG_NameStartChar* ':' TAG_NameStartChar* 
    ; 

TAG_WHITESPACE 
    : [ \t\r\n] -> skip 
    ; 

Und die correspoding Parser-Regel für die:

htmlElement 
    : TAG_OPEN htmlTagName htmlAttribute* TAG_CLOSE htmlContent TAG_OPEN TAG_SLASH htmlTagName TAG_CLOSE 
    | TAG_OPEN htmlTagName htmlAttribute* TAG_SLASH_CLOSE 
    | TAG_OPEN htmlTagName htmlAttribute* TAG_CLOSE 
    | TAG_OPEN TAG_SLASH htmlTagName TAG_CLOSE 
// | jspDirective 
// | jspDeclaration 
    | scriptlet 
    | script 
    | style 
    ; 

Ich versuche, die oben genannten Regeln mit dem folgenden zu erweitern:

scriptlet 
    : JSP_TAG_OPEN jspElement jspElementName jspElementAttribute* JSP_TAG_CLOSE 
    //|SCRIPTLET 
    ; 

jspElementName 
    : TAG_NAME 
    ; 

jspElementAttribute 
    : jspAttributeName TAG_EQUALS jspAttributeValue 
    ; 

jspAttributeName 
    : TAG_NAME 
    ; 

jspAttributeValue 
    : ATTVALUE_VALUE 
    ; 

jspElement 
    : jspDirective 
    | jspExpression 
    | jspDeclaration 
    | jspFragment 
    ; 

jspDirective  
    : JSP_DIRECTIVE_SIGN 
    ; 

jspExpression 
    : JSP_EXPRESSION_SIGN 
    ; 

jspDeclaration 
    : JSP_DECLARATION_SIGN 
    ; 

jspFragment 
    : JSP_FRAGMENT_SIGN 
    ; 

Die Lexerregeln sind:

JSP_TAG_OPEN 
    : '<%' ' '* 
    ; 

JSP_DIRECTIVE_SIGN 
    : '@' 
    ; 

JSP_EXPRESSION_SIGN 
    : '=' 
    ; 

JSP_DECLARATION_SIGN 
    : '!' 
    ; 

JSP_FRAGMENT_SIGN 
    : [ ]+ 
    ; 

JSP_TAG_CLOSE 
    : '%>' 
    ; 

Aber das Problem, das ich denke, ist, dass, wann immer ein < Zeichen die lexer Regel für TAG_OPEN beginnt, zu laufen, anstatt zu warten, um zu sehen, ob das ein jsp Tag <% ist.

Also, wenn ich versuche, eine kleine html mit folgendem Inhalt zu analysieren:

<html> 
<title>Statement Load page</title> 
<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" 
    prefix="html"%> 

ich diese Störung erhalte:

line 3:2 no viable alternative at input '@ taglib uri="http://jakarta.apache.org/struts/tags-html"\r\n\tprefix="html"%>\r\n' 

Antwort

0

Ok, ich habe für jsp mit einer Grammatik kommen jetzt. Ich teile das hier mit, wenn das anderen hilft. Außerdem würde ich mich freuen, wenn jemand ein Update vorschlägt, Probleme aufzeigt oder hilft, die Grammatik besser zu machen.

Lexer Grammatik:

lexer grammar HTMLLexer; 


HTML_COMMENT 
    : '<!--' .*? '-->' 
    ; 

HTML_CONDITIONAL_COMMENT 
    : '<![' .*? ']>' 
    ; 

JSP_COMMENT 
    : '<%--' .*? '--%>' 
    ; 

XML_DECLARATION 
    : '<?xml' .*? '>' 
    ; 

SCRIPT_OPEN 
    : '<script' ->pushMode(SCRIPT) 
    ; 

DIRECTIVE_TAG_OPEN 
    : '<%@' -> pushMode(TAG) 
    ; 

SCRIPTLET_TAG_OPEN 
    : ('<%!' | '<%=' | '<%') ->pushMode(SCRIPTVALUE) 
    ; 

// 
// 
CDATA 
    : '<![CDATA[' .*? ']]>' 
    ; 

DTD 
    : '<!' .*? '>' 
    ; 

//SCRIPTLET 
// : '<?' .*? '?>' 
// | '<%' .*? '%>' 
// ; 

SEA_WS 
    : (' '|'\t'|'\r'? '\n')+ 
    ; 


LINK_OPEN 
    : '<link' ->pushMode(LINK) 
    ; 

STYLE_OPEN 
    : '<style' ->pushMode(STYLE) 
    ; 

TAG_OPEN 
    : '<' ->pushMode(TAG) 
    ; 

HTML_TEXT 
    : ~'<'+ 
    ; 

// 
// tag declarations 
// 
mode TAG; 

JSP_TAG_CLOSE 
    : '%>' -> popMode 
    ; 

TAG_CLOSE 
    : '>' -> popMode 
    ; 

TAG_SLASH_CLOSE 
    : '/>' -> popMode 
    ; 

TAG_SLASH 
    : '/' 
    ; 

// 
// lexing mode for attribute values 
// 
TAG_EQUALS 
    : '=' -> pushMode(ATTVALUE) 
    ; 

TAG_NAME 
    : TAG_NameStartChar TAG_NameChar* 
// | TAG_NameStartChar* ':' TAG_NameStartChar* 
    ; 

TAG_COLON 
    : ':' 
    ; 

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

// 
// <scripts> 
// 
mode SCRIPT; 

SCRIPT_TAG_FULL_CLOSE 
    : '</script>' ->popMode 
    ; 


SCRIPT_TAG_CLOSE 
    : '>' -> popMode 
    ; 

SCRIPT_TAG_SLASH_CLOSE 
    : '/>' -> popMode 
    ; 

SCRIPT_EQUALS 
    : ' '* '=' ' '* 
    ; 

SCRIPLET_INSIDE_SCRIPT 
    : '<%' ->pushMode(SCRIPTVALUE) 
    ; 

SCRIPT_ATTRIBUTE 
    : SCRIPT_ATTCHARS  
    ; 

fragment SCRIPT_ATTCHARS 
    : SCRIPT_ATTCHAR+ ' '? 
    ; 

SCRIPT_WHITESPACE 
    : [\r\n\t]+ -> channel(HIDDEN) 
    ; 

WORD 
    : [ a-zA-Z]+ 
    ; 

QUOTE 
    : '"' ' '* 
    ; 

fragment SCRIPT_ATTCHAR 
    : '-' 
    | '_' 
    | '.' 
    | '/' 
    | ',' 
    | ';' 
    | '\'' 
    | '"' 
    | [0-9a-zA-Z] 
    ;  

// 
// <link> 
// 
mode LINK; 

LINK_BODY 
    : .*? '</link>' ->popMode 
    ; 

LINK_SHORT_BODY 
    : '/>' ->popMode 
    ; 

LINK_WS 
    : [ \r\n\t]+ -> channel(HIDDEN) 
    ; 

LINK_NONSLASH_BODY 
    : .*? '>' ->popMode 
    ; 


// 
// <styles> 
// 
mode STYLE; 

STYLE_BODY 
    : .*? '</style>' -> popMode 
    ; 

STYLE_SHORT_BODY 
    : .*? '</>' -> popMode 
    ; 

// 
// 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 
    : '\'' ~[<']* '\'' 
    ; 

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

Parser Grammatik:

parser grammar HTMLParser; 

options { tokenVocab=HTMLLexer; } 

htmlDocument 
    : (scriptlet | SEA_WS)* xml? (scriptlet | SEA_WS)* dtd? (scriptlet | SEA_WS)* htmlElements* 
    ; 

htmlElements 
    : htmlMisc* htmlElement htmlMisc* 
    ; 

htmlElement 
    : script 
    | link 
    | style 
    | scriptlet 
    | TAG_OPEN htmlTagName htmlAttribute* TAG_CLOSE htmlContent TAG_OPEN TAG_SLASH htmlTagName TAG_CLOSE 
    | TAG_OPEN htmlTagName htmlAttribute* TAG_SLASH_CLOSE 
    | TAG_OPEN htmlTagName htmlAttribute* TAG_CLOSE 
    | TAG_OPEN TAG_SLASH htmlTagName TAG_CLOSE 
    ; 

htmlContent 
    : htmlChardata? ((htmlElement | xhtmlCDATA | htmlComment) htmlChardata?)* 
    ; 

htmlAttribute 
    : htmlAttributeName TAG_EQUALS htmlAttributeValue 
    | htmlAttributeName 
    ; 

htmlAttributeName 
    : TAG_NAME 
    ; 

htmlAttributeValue 
    : ATTVALUE_VALUE 
    ; 

htmlTagName 
    : TAG_NAME 
    | tagKey TAG_COLON tagVal 
    ; 

tagKey 
    : TAG_NAME 
    ; 

tagVal 
    : TAG_NAME 
    ; 

htmlChardata 
    : HTML_TEXT 
    | SEA_WS 
    ; 

htmlMisc 
    : htmlComment 
    | jspComment 
    | SEA_WS 
    ; 

htmlComment 
    : HTML_COMMENT 
    | HTML_CONDITIONAL_COMMENT 
    ; 

jspComment 
    : JSP_COMMENT 
    ; 

xhtmlCDATA 
    : CDATA 
    ; 

dtd 
    : DTD 
    ; 

xml 
    : XML_DECLARATION 
    ; 

scriptlet 
    : DIRECTIVE_TAG_OPEN jspElementName jspElementAttribute* JSP_TAG_CLOSE 
    | 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*  
    ; 

script 
    : SCRIPT_OPEN scriptAttribute* SCRIPT_TAG_CLOSE htmlContent* SCRIPT_TAG_FULL_CLOSE 
    | SCRIPT_OPEN scriptAttribute* SCRIPT_TAG_SLASH_CLOSE 
    ; 

scriptAttribute 
    : scriptAttributeName SCRIPT_EQUALS QUOTE scriptlet scriptAttributeValue* QUOTE 
    | scriptAttributeName SCRIPT_EQUALS scriptAttributeValue 
    | scriptAttributeName 
    ; 

scriptAttributeName 
    : WORD 
    ; 

scriptAttributeValue 
    : SCRIPT_ATTRIBUTE 
    ; 

link 
    : LINK_OPEN (LINK_BODY | LINK_SHORT_BODY | LINK_NONSLASH_BODY) 
    | LINK_OPEN scriptlet* (LINK_BODY | LINK_SHORT_BODY | LINK_NONSLASH_BODY) 
    ; 

style 
    : STYLE_OPEN (STYLE_BODY | STYLE_SHORT_BODY) 
    ; 

Edit: Ich habe den Parser und Lexer Grammatik seit meinem letzten Eintrag geändert. Ich habe jetzt ein Problem beim Parsen einer JSP-Datei. Eine Probe jsp ist:

<html> 
<title>Statement Load page</title> 

<script type="text/javascript" src="<%= request.getContextPath() %>"></script> 
<script type="text/javascript" src="<%= request.getContextPath() %>/scripts/Main.js"></script> 

<body> 
</body> 
</html> 

Während diese Datei Parsen, erhalte ich:

line 4:0 mismatched input '<script' expecting '<' 
line 5:31 no viable alternative at input '<script type="text/javascript" src' 

Das heißt, während "< Skript" Tag der Parser die 'script' Regel nicht zu begegnen Eingabe, aber wahrscheinlich behandelt es als andere 'htmlElement'. Aber ich bin mir nicht sicher.

Der relevante Teil der Parser Grammatik ist:

script 
    : SCRIPT_OPEN scriptAttribute* SCRIPT_TAG_CLOSE htmlContent* SCRIPT_TAG_FULL_CLOSE 
    | SCRIPT_OPEN scriptAttribute* SCRIPT_TAG_SLASH_CLOSE 
    ; 

scriptAttribute 
    : scriptAttributeName SCRIPT_EQUALS QUOTE scriptlet scriptAttributeValue* QUOTE 
    | scriptAttributeName SCRIPT_EQUALS scriptAttributeValue 
    | scriptAttributeName 
    ; 

scriptAttributeName 
    : WORD 
    ; 

scriptAttributeValue 
    : SCRIPT_ATTRIBUTE 
    ; 
+0

Ich habe meine Grammatik wurde Modifizieren den Script-Tag in mehr Details zu analysieren. Aber ich habe Probleme beim Parsen. @Bart Kiers könntest du bitte einen Blick darauf werfen. –