From 90af66962f0530947c705ed9f0ac83e46c580911 Mon Sep 17 00:00:00 2001 From: Sergey Date: Tue, 21 Feb 2017 12:59:52 -0800 Subject: [PATCH] Grammar with support for VFEL methods --- pmd-visualforce/etc/grammar/VfParser.jjt | 324 ++++++++++++++++------- 1 file changed, 229 insertions(+), 95 deletions(-) diff --git a/pmd-visualforce/etc/grammar/VfParser.jjt b/pmd-visualforce/etc/grammar/VfParser.jjt index d85aa6ba7a..175e644b3a 100644 --- a/pmd-visualforce/etc/grammar/VfParser.jjt +++ b/pmd-visualforce/etc/grammar/VfParser.jjt @@ -15,7 +15,7 @@ PARSER_BEGIN(VfParser) package net.sourceforge.pmd.lang.vf.ast; import net.sourceforge.pmd.lang.ast.CharStream; -import net.sourceforge.pmd.lang.ast.TokenMgrError; +import net.sourceforge.pmd.lang.vf.TokenMgrError; public class VfParser { @@ -49,7 +49,6 @@ public class VfParser { PARSER_END(VfParser) /** ************************* VF LEXICON **************************** */ -// functionCall: identifier LPAREN expression? (COMMA expression)* RPAREN; <*> TOKEN : { @@ -66,7 +65,7 @@ PARSER_END(VfParser) "\u0030"-"\u0039" ] > | <#ALPHANUM_CHAR: ( | ) > -| <#IDENTIFIER_CHAR: ( | [ "_", "-", ".", ":" ] ) > +| <#IDENTIFIER_CHAR: ( | [ "_", "-", ":" ] ) > | <#IDENTIFIER: ()* > | <#XMLNAME: ( | "_" | ":") ()* > | <#QUOTED_STRING_NO_BREAKS: ( "'" ( ~["'", "\r", "\n"] )* "'" ) @@ -81,6 +80,8 @@ PARSER_END(VfParser) | <#NO_LT_OR_OPENBRACE: (~["<","{"])> | <#NO_ENDTAG_START: (~["<"]~["/"]) > | <#TEXT_IN_EL: (~["}", "'", "\""])+ > +| <#CLOSEBRACE: ("}")> +| <#DOT: "." > } @@ -89,7 +90,7 @@ PARSER_END(VfParser) < ()+ > } - SPECIAL_TOKEN : + SPECIAL_TOKEN: { < ()+ > } @@ -109,10 +110,66 @@ PARSER_END(VfParser) TOKEN : { - | )* "}" ) > + : ElTagState | |)+ > } + TOKEN : +{ + + | + | + | + | + | + | + | + | > + | + | + | + | + | + | + | + | + | + | + | " | "!=" ) > + | =" > + | + | " > + | + | + | > + | )+ > + | > + | + | + +} + + TOKEN : +{ + )? > : AfterTagState +} + + TOKEN : +{ + )? > : AttrValueBetweenSingleQuotesState +} + + TOKEN : +{ + )? > : AttrValueBetweenDoubleQuotesState +} + TOKEN : { )+ > @@ -157,33 +214,22 @@ PARSER_END(VfParser) { )? "'"> : AttrValueBetweenSingleQuotesState | )? "\"">: AttrValueBetweenDoubleQuotesState -| { input_stream.backup(1);} : AttrValueNoQuotesState | : InTagState //support for empty attributes } - TOKEN: -{ - | )* "}" > -} - - TOKEN : -{ - : InTagState -| - -} - TOKEN : { : InTagState +| )? > : ElAttribTagStateSQ | } TOKEN : { - : InTagState -| : InTagState + | )? > : ElAttribTagStateDQ + | } @@ -262,7 +308,7 @@ void ContentElement() #void : {} { ( - CommentTag() + CommentTag() | Element() | CData() | HtmlScript() @@ -276,18 +322,10 @@ void ContentElement() #void : * tag is an xml-tag "<...>" or CDATA "<![CDATA[...]]>". * Text consists of unparsed text and/or Expression Language expressions. */ -void Text() : +void Text() #void : +{} { - StringBuffer content = new StringBuffer(); - String tmp; -} -{ - ( - tmp = UnparsedText() { content.append(tmp); } - | tmp = ElExpression() { content.append(tmp); } - )+ - {jjtThis.setImage(content.toString());} - + ( LOOKAHEAD(ElExpression()) ElExpression() | UnparsedText() )+ } String UnparsedText() : @@ -300,20 +338,6 @@ String UnparsedText() : } } -String UnparsedTextNoWhitespace() #UnparsedText : -{ Token t;} -{ - ( - t = - ) - { - jjtThis.setImage(t.image); - return t.image; - } -} - - - /** * Text that contains no single quotes, and that does not contain the start * of a EL expression. @@ -345,24 +369,164 @@ String UnparsedTextNoDoubleQuotes() #UnparsedText : /** * An EL expression, not within an attribute value. */ -String ElExpression() : -{ Token t; } +void ElExpression() : +{} { - t = - { - jjtThis.setImage(expressionContent(t.image)); - return t.image; - } + + (Expression())+ + } -String ElExpressionInAttribute() #ElExpression : -{ Token t; } +void Expression() : +{} { - t = - { - jjtThis.setImage(expressionContent(t.image)); - return t.image; - } + ConditionalExpression() [ AssignmentOperator() Expression() ] +} + +void AssignmentOperator() #void : +{} +{ + | | | | | +} + +void ConditionalExpression() #void : +{} +{ + ConditionalOrExpression() [ Expression() ConditionalExpression() ] +} + +void ConditionalOrExpression() #void : +{} +{ + ConditionalAndExpression() ( ConditionalAndExpression() )* +} + +void ConditionalAndExpression() #void : +{} +{ + PowerExpression() ( PowerExpression() )* +} + +void PowerExpression() #void : +{} +{ + ConcatExpression() ( ConcatExpression() )* +} + +void ConcatExpression() #void : +{} +{ + EqualityExpression() ( EqualityExpression() )* +} + +void EqualityExpression() #void : +{} +{ + RelationalExpression() ( ( | ) RelationalExpression() )* +} + +void RelationalExpression() #void : +{} +{ + AdditiveExpression() ( ( | | | ) AdditiveExpression() )* +} + +void AdditiveExpression() #void : +{} +{ + MultiplicativeExpression() ( LOOKAHEAD(2) ( | ) MultiplicativeExpression() )* +} + +void MultiplicativeExpression() #void : +{} +{ + UnaryExpression() ( ( |
| ) UnaryExpression() )* +} + +void UnaryExpression() #void : +{} +{ + ( | ) UnaryExpression() + | UnaryExpressionNotPlusMinus() +} + +void UnaryExpressionNotPlusMinus() #void : +{} +{ + ( ) UnaryExpression() +| PrimaryExpression() +} + +void PrimaryExpression() #void : +{} +{ + PrimaryPrefix() ( LOOKAHEAD(2) PrimarySuffix() )* +} + +void PrimaryPrefix() #void : +{} +{ + Literal() + | Identifier() + | Expression() +} + +void PrimarySuffix() #void : +{} +{ + Expression() + | Identifier() + | Arguments() +} + +void Arguments() #void : +{} +{ + [ ArgumentList() ] +} + +void ArgumentList() #void: +{} +{ + Expression() ( Expression() )* +} + +void Literal() : +{ String s; Token t; } +{ + t = { jjtThis.setImage(t.image);} + | t = { jjtThis.setImage(t.image);} + | s = BooleanLiteral() { jjtThis.setImage(s);} + | s = NullLiteral() { jjtThis.setImage(s);} + +} + +String BooleanLiteral() #void : +{ Token t; } +{ + ( t = + | t = + ) { return t.image; } +} + +String NullLiteral() #void : +{ Token t; } +{ + t = { return t.image;} +} + +void Identifier() : +{ Token t; } +{ + t = { jjtThis.setImage(t.image);} +} + + +void ElExpressionInAttribute() #ElExpression : +{} +{ + Expression() + | Expression() } void CData() : @@ -403,7 +567,7 @@ void Element() : (Content()) - ( + ( LOOKAHEAD(2) endTag = {tagRegister.closeTag(endTag.image);} )? ) @@ -421,8 +585,7 @@ void Attribute() : { t = { jjtThis.setName(t.image); } ( - - AttributeValue() + AttributeValue() ) } @@ -432,51 +595,22 @@ void Attribute() : * are parsed as sub-nodes of the AttributeValue node. */ void AttributeValue() : - { - StringBuffer content = new StringBuffer(); - String tmp; - Token t = null ; - } + {} { ( ( - ( ( tmp = UnparsedTextNoDoubleQuotes() - | tmp = QuoteIndependentAttributeValueContent() - ) { content.append(tmp); } )* + ( ( UnparsedTextNoDoubleQuotes() | ElExpressionInAttribute() ) )* ( ) ) | ( - ( ( tmp = UnparsedTextNoSingleQuotes() | tmp = QuoteIndependentAttributeValueContent() ) - { content.append(tmp); } )* + ( ( UnparsedTextNoSingleQuotes() | ElExpressionInAttribute() ) )* ( ) ) - | - ( - ( ( tmp = UnparsedTextNoWhitespace() | tmp = QuoteIndependentAttributeValueContent() ) - { content.append(tmp); } - )* - ( ) - ) | ) - { jjtThis.setImage( content.toString() ); - } } -/** - * Partial content of an attribute value that can contain all quotes. - * This groups EL expressions. - */ -String QuoteIndependentAttributeValueContent() #void : -{ String tmp; } -{ - ( tmp = ElExpressionInAttribute() - ) - { return tmp; } -} - - void CommentTag() : { StringBuffer content = new StringBuffer();