/**
* Copyright (C) 2013-2016 The Rythm Engine project
* for LICENSE and other details see:
* https://github.com/rythmengine/rythmengine
*/
package org.rythmengine.internal.parser;
import com.stevesoft.pat.Regex;
import org.rythmengine.Rythm;
import org.rythmengine.RythmEngine;
import org.rythmengine.Sandbox;
import org.rythmengine.internal.*;
import org.rythmengine.internal.parser.build_in.CaretParserFactoryBase;
import org.rythmengine.logger.ILogger;
import org.rythmengine.logger.Logger;
import org.rythmengine.utils.S;
import java.util.regex.Pattern;
public abstract class ParserBase implements IParser {
public static final ParserBase NULL_INST = new ParserBase() {
@Override
public Token go() {
return null;
}
};
protected final static ILogger logger = Logger.get(IParser.class);
public static Pattern pattern(String regex, Object... args) {
if (0 < args.length) regex = String.format(regex, args);
return Pattern.compile(regex, Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
}
private final IDialect d_;
private final IContext c_;
protected final RythmEngine engine_;
private ParserBase() {
d_ = null;
c_ = null;
engine_ = null;
}
protected ParserBase(IContext context) {
if (null == context) throw new NullPointerException();
d_ = context.getDialect();
c_ = context;
engine_ = context.getEngine();
}
protected final IDialect dialect() {
return d_;
}
protected final String a() {
return d_.a();
}
protected final String remain() {
return c_.getRemain();
}
protected final int currentLine() {
return c_.currentLine();
}
protected final char peek() {
return c_.peek();
}
protected final char pop() {
return c_.pop();
}
public final IContext ctx() {
return c_;
}
protected final CodeBuilder builder() {
return c_.getCodeBuilder();
}
protected final void step(int i) {
c_.step(i);
}
protected final void raiseParseException(String msg, Object... args) {
CaretParserFactoryBase.raiseParseException(ctx(), msg, args);
}
protected final void checkRestrictedClass(String code) {
if (Rythm.insideSandbox()) {
String s = Sandbox.hasAccessToRestrictedClasses(ctx().getEngine(), code);
if (S.notEmpty(s)) {
raiseParseException("Access to restricted class [%s] is blocked in sandbox mode", s);
}
}
}
protected boolean isLastBuilderLiteral() {
IContext ctx = ctx();
if (ctx.cursor() == 0) return false;
CodeBuilder cb = ctx.getCodeBuilder();
return cb.isLastBuilderLiteral();
}
protected void processFollowingOpenBraceAndLineBreak(boolean leadingLB) {
IContext ctx = ctx();
int cnt = 0; int lbCnt = 0;
StringBuilder sb = new StringBuilder();
boolean braceOpen = false;
while(ctx.hasRemain()) {
char c0 = ctx.pop();cnt--;
if (c0 == ' ' || c0 == '\t') {
if (braceOpen) sb.append(c0);
continue;
} else if (c0 == '\n') {
if (braceOpen) {
if (!leadingLB) sb.append("\n");
ctx.getCodeBuilder().addBuilder(new Token.StringToken(sb.toString(), ctx));
break;
} else {
lbCnt++;
continue;
}
} else if (c0 == '{') {
if (!braceOpen) {
braceOpen = true;
cnt = 0;
continue;
} else {
ctx.step(cnt);
break;
}
} else {
ctx.step(cnt);
break;
}
}
}
// -- for testing purpose
public static void p(int i, Regex r) {
if (0 == i) {
System.out.println(i + ": " + r.stringMatched());
} else {
System.out.println(i + ": " + r.stringMatched(i));
}
}
public static void p(String s, Regex r) {
if (r.search(s)) p(r);
}
public static void p(String s, Regex r, int max) {
if (r.search(s)) p(r, max);
}
public static void p(Regex r, int max) {
for (int i = 0; i < max; ++i) {
p(i, r);
}
}
public static void p(Regex r) {
p(r, 6);
}
}