📄 fmparser.java
字号:
/* Generated By:JavaCC: Do not edit this line. FMParser.java */
package freemarker.core;
import freemarker.template.*;
import freemarker.template.utility.StringUtil;
import freemarker.template.utility.DeepUnwrap;
import java.io.*;
import java.util.*;
/**
* This class is generated by JavaCC from a grammar file.
*/
public class FMParser implements FMParserConstants {
// Necessary for adding macros and setting location info.
Template template;
private String templateName;
// variables that keep track of whether we are in a loop or a switch.
private int loopNesting, switchNesting;
private boolean inMacro, inFunction, stripWhitespace, stripText;
private LinkedList escapes = new LinkedList();
private int contentNesting; // for stripText
/**
* Create an FM expression parser using a string.
*/
static public FMParser createExpressionParser(String s) {
SimpleCharStream scs = new SimpleCharStream(new StringReader(s), 1, 1, s.length());
FMParserTokenManager token_source = new FMParserTokenManager(scs);
token_source.SwitchTo(FMParserConstants.FM_EXPRESSION);
return new FMParser(token_source);
}
/**
* Constructs a new parser object.
* @param template The template associated with this parser.
* @param reader The character stream to use as input
* @param strictEscapeSyntax Whether FreeMarker directives must start with a #
*/
public FMParser(Template template, Reader reader, boolean strictEscapeSyntax, boolean stripWhitespace) {
this(reader);
this.template = template;
token_source.strictEscapeSyntax = strictEscapeSyntax;
this.templateName = template != null ? template.getName() : "";
token_source.templateName = templateName;
this.stripWhitespace = stripWhitespace;
}
public FMParser(Template template, Reader reader, boolean strictEscapeSyntax, boolean stripWhitespace, int tagSyntax) {
this(template, reader, strictEscapeSyntax, stripWhitespace);
switch (tagSyntax) {
case Configuration.AUTO_DETECT_TAG_SYNTAX :
token_source.autodetectTagSyntax = true;
break;
case Configuration.ANGLE_BRACKET_TAG_SYNTAX :
token_source.altDirectiveSyntax = false;
break;
case Configuration.SQUARE_BRACKET_TAG_SYNTAX :
token_source.altDirectiveSyntax = true;
break;
default : throw new IllegalArgumentException("Illegal argument for tagSyntax");
}
}
public FMParser(String template) {
this(null, new StringReader(template), true, true);
}
private String getErrorStart(Token t) {
return "Error in template: " + template.getName()
+ "\non line " + t.beginLine + ", column " + t.beginColumn;
}
/**
* Throw an exception if the expression passed in is a String
* Literal
*/
private void notStringLiteral(Expression exp, String expected) throws ParseException {
if (exp instanceof StringLiteral) {
String msg = "Error " + exp.getStartLocation()
+ "\nFound string literal: " + exp
+ "\nExpecting: " + expected;
throw new ParseException(msg, exp);
}
}
/**
* Throw an exception if the expression passed in is a Number
* Literal
*/
private void notNumberLiteral(Expression exp, String expected) throws ParseException {
if (exp instanceof NumberLiteral) {
String msg = "Error " + exp.getStartLocation()
+ "\nFound number literal: " + exp.getCanonicalForm()
+ "\nExpecting " + expected;
throw new ParseException(msg, exp);
}
}
/**
* Throw an exception if the expression passed in is a boolean
* Literal
*/
private void notBooleanLiteral(Expression exp, String expected) throws ParseException {
if (exp instanceof BooleanLiteral) {
String msg = "Error " + exp.getStartLocation()
+ "\nFound: " + exp.getCanonicalForm()
+ "\nExpecting " + expected;
throw new ParseException(msg, exp);
}
}
/**
* Throw an exception if the expression passed in is a Hash
* Literal
*/
private void notHashLiteral(Expression exp, String expected) throws ParseException {
if (exp instanceof HashLiteral) {
String msg = "Error " + exp.getStartLocation()
+ "\nFound hash literal: " + exp.getCanonicalForm()
+ "\nExpecting " + expected;
throw new ParseException(msg, exp);
}
}
/**
* Throw an exception if the expression passed in is a List
* Literal
*/
private void notListLiteral(Expression exp, String expected)
throws ParseException
{
if (exp instanceof ListLiteral) {
String msg = "Error " + exp.getStartLocation()
+ "\nFound list literal: " + exp.getCanonicalForm()
+ "\nExpecting " + expected;
throw new ParseException(msg, exp);
}
}
/**
* Throw an exception if the expression passed in is a literal
* other than of the numerical type
*/
private void numberLiteralOnly(Expression exp) throws ParseException {
notStringLiteral(exp, "number");
notListLiteral(exp, "number");
notHashLiteral(exp, "number");
notBooleanLiteral(exp, "number");
}
/**
* Throw an exception if the expression passed in is
* not a string.
*/
private void stringLiteralOnly(Expression exp) throws ParseException {
notNumberLiteral(exp, "number");
notListLiteral(exp, "number");
notHashLiteral(exp, "number");
notBooleanLiteral(exp, "number");
}
/**
* Throw an exception if the expression passed in is a literal
* other than of the boolean type
*/
private void booleanLiteralOnly(Expression exp) throws ParseException {
notStringLiteral(exp, "boolean (true/false)");
notListLiteral(exp, "boolean (true/false)");
notHashLiteral(exp, "boolean (true/false)");
notNumberLiteral(exp, "boolean (true/false)");
}
private Expression escapedExpression(Expression exp) {
if(!escapes.isEmpty()) {
return ((EscapeBlock)escapes.getFirst()).doEscape(exp);
}
return exp;
}
private boolean getBoolean(Expression exp) throws ParseException {
TemplateModel tm = null;
try {
tm = exp.getAsTemplateModel(null);
} catch (Exception e) {
throw new ParseException(e.getMessage()
+ "\nCould not evaluate expression: "
+ exp.getCanonicalForm()
+ exp.getStartLocation(), exp);
}
if (tm instanceof TemplateBooleanModel) {
try {
return ((TemplateBooleanModel) tm).getAsBoolean();
} catch (TemplateModelException tme) {
}
}
if (tm instanceof TemplateScalarModel) {
try {
return StringUtil.getYesNo(((TemplateScalarModel) tm).getAsString());
} catch (Exception e) {
throw new ParseException(e.getMessage()
+ "\nExpecting yes/no, found: " + exp.getCanonicalForm()
+ exp.getStartLocation(), exp);
}
}
throw new ParseException("Expecting boolean (yes/no) parameter" + exp.getStartLocation(), exp);
}
// Now the actual parsing code, starting
// with the productions for FreeMarker's
// expression syntax.
/**
* This is the same as OrExpression, since
* the OR is the operator with the lowest
* precedence.
*/
final public Expression Expression() throws ParseException {
Expression exp;
exp = OrExpression();
{if (true) return exp;}
throw new Error("Missing return statement in function");
}
/**
* Lowest level expression, a literal, a variable,
* or a possibly more complex expression bounded
* by parentheses.
*/
final public Expression PrimaryExpression() throws ParseException {
Expression exp;
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case INTEGER:
case DECIMAL:
exp = NumberLiteral();
break;
case OPEN_BRACE:
exp = HashLiteral();
break;
case STRING_LITERAL:
case RAW_STRING:
exp = StringLiteral(true);
break;
case FALSE:
case TRUE:
exp = BooleanLiteral();
break;
case OPEN_BRACKET:
exp = ListLiteral();
break;
case ID:
exp = Identifier();
break;
case OPEN_PAREN:
exp = Parenthesis();
break;
case DOT:
exp = BuiltinVariable();
break;
default:
jj_la1[0] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
label_1:
while (true) {
if (jj_2_1(2147483647)) {
;
} else {
break label_1;
}
exp = AddSubExpression(exp);
}
{if (true) return exp;}
throw new Error("Missing return statement in function");
}
final public Expression Parenthesis() throws ParseException {
Expression exp, result;
Token start, end;
start = jj_consume_token(OPEN_PAREN);
exp = Expression();
end = jj_consume_token(CLOSE_PAREN);
result = new ParentheticalExpression(exp);
result.setLocation(template, start, end);
{if (true) return result;}
throw new Error("Missing return statement in function");
}
/**
* A primary expression preceded by zero or
* more unary operators. (The only unary operator we
* currently have is the NOT.)
*/
final public Expression UnaryExpression() throws ParseException {
Expression exp, result;
boolean haveNot = false;
Token t = null, start=null;
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case PLUS:
case MINUS:
result = UnaryPlusMinusExpression();
break;
case EXCLAM:
result = NotExpression();
break;
case STRING_LITERAL:
case RAW_STRING:
case FALSE:
case TRUE:
case INTEGER:
case DECIMAL:
case DOT:
case OPEN_BRACKET:
case OPEN_PAREN:
case OPEN_BRACE:
case ID:
result = PrimaryExpression();
break;
default:
jj_la1[1] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
{if (true) return result;}
throw new Error("Missing return statement in function");
}
final public Expression NotExpression() throws ParseException {
Token t;
Expression exp, result=null;
ArrayList nots = new ArrayList();
label_2:
while (true) {
t = jj_consume_token(EXCLAM);
nots.add(t);
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case EXCLAM:
;
break;
default:
jj_la1[2] = jj_gen;
break label_2;
}
}
exp = PrimaryExpression();
for (int i=0; i<nots.size(); i++) {
result = new NotExpression(exp);
Token tok = (Token) nots.get(nots.size() -i -1);
result.setLocation(template, tok, exp);
exp = result;
}
{if (true) return result;}
throw new Error("Missing return statement in function");
}
final public Expression UnaryPlusMinusExpression() throws ParseException {
Expression exp, result;
boolean isMinus = false;
Token t;
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case PLUS:
t = jj_consume_token(PLUS);
break;
case MINUS:
t = jj_consume_token(MINUS);
isMinus = true;
break;
default:
jj_la1[3] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
exp = PrimaryExpression();
result = new UnaryPlusMinusExpression(exp, isMinus);
result.setLocation(template, t, exp);
{if (true) return result;}
throw new Error("Missing return statement in function");
}
final public Expression AdditiveExpression() throws ParseException {
Expression lhs, rhs, result;
boolean plus;
lhs = MultiplicativeExpression();
result = lhs;
label_3:
while (true) {
if (jj_2_2(2147483647)) {
;
} else {
break label_3;
}
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case PLUS:
jj_consume_token(PLUS);
plus = true;
break;
case MINUS:
jj_consume_token(MINUS);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -