com.greenlaw110.rythm.internal.parser.build_in.ExpressionParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rythm-engine Show documentation
Show all versions of rythm-engine Show documentation
A strong typed high performance Java Template engine with .Net Razor like syntax
The newest version!
/*
* Copyright (C) 2013 The Rythm Engine project
* Gelin Luo
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.greenlaw110.rythm.internal.parser.build_in;
import com.greenlaw110.rythm.exception.DialectNotSupportException;
import com.greenlaw110.rythm.internal.*;
import com.greenlaw110.rythm.internal.dialect.BasicRythm;
import com.greenlaw110.rythm.internal.dialect.Rythm;
import com.greenlaw110.rythm.internal.dialect.SimpleRythm;
import com.greenlaw110.rythm.internal.parser.CodeToken;
import com.greenlaw110.rythm.internal.parser.ParserBase;
import com.greenlaw110.rythm.internal.parser.Patterns;
import com.greenlaw110.rythm.utils.S;
import com.greenlaw110.rythm.utils.TextBuilder;
import com.stevesoft.pat.Regex;
/**
* Single line expression parser
*
* @author luog
*/
public class ExpressionParser extends CaretParserFactoryBase {
/**
* Return symbol with transformer extension stripped off
*
* @param symbol
* @param context
* @return
*/
public static String assertBasic(String symbol, IContext context) {
if (symbol.contains("_utils.sep(\"")) return symbol;// Rythm builtin expression TODO: generalize
//String s = Token.stripJavaExtension(symbol, context);
//s = S.stripBrace(s);
String s = symbol;
boolean isSimple = Patterns.VarName.matches(s);
IContext ctx = context;
if (!isSimple) {
throw new TemplateParser.ComplexExpressionException(ctx);
}
return s;
}
static class ExpressionToken extends CodeToken {
public ExpressionToken(String s, IContext context) {
super(s, context);
checkRestrictedClass(ctx, s);
if (s.contains("_utils.sep(\"")) return;
if (context.getDialect() instanceof BasicRythm) {
if (s.startsWith("(")) {
s = S.stripBrace(s);
}
// basic rythm dialect support only simple expression
s = assertBasic(s, context);
// find out array and it's dimension
int d = 0;
for (int i = 0; i < s.length(); ++i) {
if (s.charAt(i) == '[') d++;
}
int pos = s.indexOf("[");
if (pos != -1) {
s = s.substring(0, pos);
}
String type = "Object";
for (int i = 0; i < d; ++i) {
type = type + "[]";
}
context.getCodeBuilder().addRenderArgsIfNotDeclared(context.currentLine(), type, s);
}
}
@Override
public void output() {
boolean needsPrint = true;
int pos = s.indexOf("(");
if (pos != -1) {
String tagName = s.substring(0, pos).trim();
if (!S.isEmpty(tagName)) {
needsPrint = ctx.getCodeBuilder().needsPrint(tagName);
}
}
outputExpression(needsPrint);
}
}
public static String processPositionPlaceHolder(String s) {
String rs = s.startsWith("@(") ? "@\\(([0-9]+)\\)" : "@([0-9]+)";
Regex r = new Regex(rs, "__v_${1}");
return r.replaceAll(s);
}
public static String reversePositionPlaceHolder(String s) {
Regex r = new Regex("__v_([0-9]+)", "@${1}");
return r.replaceAll(s);
}
@Override
public IParser create(IContext ctx) {
Regex r1_ = null, r2_ = null;
String caret_ = null;
final IDialect dialect = ctx.getDialect();
if (dialect instanceof Rythm || dialect instanceof SimpleRythm) {
caret_ = dialect.a();
r1_ = new Regex(String.format(patternStr(), caret_));
r2_ = new Regex(String.format("^(%s(?@())).*", caret_));
}
final Regex r1 = r1_, r2 = r2_;
final String caret = caret_;
if (null == r1 || null == r2) {
throw new DialectNotSupportException(dialect.id());
}
return new ParserBase(ctx) {
@Override
public TextBuilder go() {
String s = remain();
if (r1.search(s)) {
s = r1.stringMatched();
if (s.length() > 0) {
// String s0 = s.substring(1);
// int pos = s0.indexOf("@");
// if (pos > -1) {
// s = s.substring(0, pos + 1);
// step(s.length());
// }
//s = r1.stringMatched(1);
if (!caret.equals(s.trim())) {
step(s.length());
s = processPositionPlaceHolder(s);
s = s.replaceFirst(caret, "");
return new ExpressionToken(s, ctx());
}
}
}
s = remain();
if (r2.search(s)) {
s = r2.stringMatched(1);
if (null != s && !"@".equals(s.trim())) {
step(s.length());
s = processPositionPlaceHolder(s);
return new ExpressionToken(s.replaceFirst(caret, ""), ctx());
}
}
return null;
}
};
}
protected String patternStr() {
return "^(%s[0-9a-zA-Z_][a-zA-Z0-9_\\.]*((\\.[a-zA-Z][a-zA-Z0-9_\\.]*)*(?@[])*(?@())*)((\\.[a-zA-Z_][a-zA-Z0-9_\\.]*)*(?@[])*(?@())*)*)*";
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy