com.ajaxjs.js.jsonparser.syntax.FMS Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ajaxjs-base Show documentation
Show all versions of ajaxjs-base Show documentation
AJAXJS aims to full-stack, not only the server-side framework,
but also integrates the front-end library. It's written in HTML5 + Java, a successor to the JVM platform, efficient, secure, stable, cross-platform and many other advantages, but it abandoned the traditional enterprise architecture brought about by the large and bloated,
emphasizing the lightweight, and fast, very suitable for the Internet fast application.
/**
* Copyright Sp42 [email protected]
*
* Licensed 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.ajaxjs.js.jsonparser.syntax;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import com.ajaxjs.js.jsonparser.JsonParseException;
import com.ajaxjs.js.jsonparser.lexer.Lexer;
import com.ajaxjs.js.jsonparser.lexer.Token;
import com.ajaxjs.js.jsonparser.lexer.Tokens;
/**
* 语法解析的状态机
* Thanks to blog.csdn.net/yimengqiannian/article/details/53701275
*/
public class FMS implements States {
/**
* 词法分析器实例
*/
private Lexer lex;
/**
* 堆栈管理器
*/
private Operator opt;
/**
* 当前状态
*/
private State status;
/**
* 创建一个状态机
*
* @param jsonStr
* JSON 字符串
*/
public FMS(String jsonStr) {
if (jsonStr == null)
throw new NullPointerException("没有输入的 JSON 字符串。");
lex = new Lexer(jsonStr);
opt = new Operator(lex);
}
/**
* 开始解析 JSON 字符串
* @return MAP|LIST
*/
public Object parse() {
status = BGN;
State oldStatus = status; // 上一个状态
Token tk;
while ((tk = lex.next()) != Tokens.EOF) {
if (tk == null)
throw lex.exceptionFactory("发现不能识别的 token:" + lex.getCurChar());
if (status == VAL || status == EOF || status == ERR)
throw lex.exceptionFactory(String.format(strTpl, oldStatus.getDescription(), "结束", tk.toString()));
oldStatus = status;
status = states[oldStatus.getId()][tk.getType()];
if (status == ERR) {
String expectStr = ETS[oldStatus.getId()];
throw lex.exceptionFactory(String.format(strTpl, oldStatus.getDescription(), expectStr, tk.toString()));
}
Method m = TKOL[tk.getType()];
try {
if (m != null) // 输入 Token 操作 有点像 js 的 call/apply
status = (State) m.invoke(opt, oldStatus, status, tk);
m = status.getHandler();
if (m != null) // 目标状态操作
status = (State) m.invoke(opt, oldStatus, status, tk);
} catch (IllegalArgumentException e) {
throw lex.exceptionFactory("【反射调用】传入非法参数", e);
} catch (IllegalAccessException e) {
throw lex.exceptionFactory("【反射调用】私有方法无法调用", e);
} catch (InvocationTargetException e) {
if (e.getTargetException() instanceof JsonParseException)
throw (JsonParseException) e.getTargetException();
else
throw lex.exceptionFactory("运行时异常", e);
}
}
return opt.getCurValue();
}
private final static String strTpl = "当前状态【 %s 】, 期待【 %s 】; 但却返回 %s";
/**
* Token 输入操作列表
*/
/*INPUT —— STR NUM DESC SPLIT ARRS OBJS ARRE OBJE FALSE TRUE NIL BGN*/
private static final Method[] TKOL = {
null, null, null, null, Operator.getMethod("arrs"), Operator.getMethod("objs"), null, null, null, null, null, null
};
// STR NUM DESC SPLIT ARRS OBJS ARRE OBJE FALSE TRUE NIL BGN
final static String[] allText = {
"字符串", "数字",
Tokens.DESC.getTypeNameChinese(),
Tokens.SPLIT.getTypeNameChinese(),
Tokens.ARRS.getTypeNameChinese(),
Tokens.OBJS.getTypeNameChinese(),
Tokens.ARRE.getTypeNameChinese(),
Tokens.OBJE.getTypeNameChinese(),
Tokens.FALSE.getTypeNameChinese(),
Tokens.TRUE.getTypeNameChinese(),
Tokens.NIL.getTypeNameChinese(),
Tokens.BGN.getTypeNameChinese(),
};
// BGN ARRBV ARRAV OBJBK OBJAK OBJBV OBJAV VAL EOF ERR
final static String[] ETS = {
getExpectStr(BGN.getId()),
getExpectStr(ARRBV.getId()),
getExpectStr(ARRAV.getId()),
getExpectStr(OBJBK.getId()),
getExpectStr(OBJAK.getId()),
getExpectStr(OBJBV.getId()),
getExpectStr(OBJAV.getId()),
Tokens.EOF.getTypeNameChinese(),
Tokens.EOF.getTypeNameChinese(),
Tokens.EOF.getTypeNameChinese()
};
/**
* 获取期望 Token 描述字符串
*
* @param stateId
* 状态 id
* @return 期望 Token 描述字符串
*/
static String getExpectStr(int stateId) {
State[] stateArr = States.states[stateId];
StringBuilder sb = new StringBuilder();
for (int i = 0; i < stateArr.length; i++) {
State s = stateArr[i];
if(s != ERR) {
sb.append(allText[i]).append('|');
}
}
return sb.length() == 0 ? null : sb.deleteCharAt(sb.length() - 1).toString();
}
}