use of priv.bajdcc.LL1.syntax.handler.SyntaxException in project jMiniLang by bajdcc.
the class TestSyntax method main.
public static void main(String[] args) {
// System.out.println("Z -> `a`<,> | B | [`a` `b` Z B]");
try {
// Scanner scanner = new Scanner(System.in);
Syntax syntax = new Syntax();
syntax.addTerminal("SYMBOL", TokenType.ID, "i");
syntax.addTerminal("PLUS", TokenType.OPERATOR, OperatorType.PLUS);
syntax.addTerminal("MINUS", TokenType.OPERATOR, OperatorType.MINUS);
syntax.addTerminal("TIMES", TokenType.OPERATOR, OperatorType.TIMES);
syntax.addTerminal("DIVIDE", TokenType.OPERATOR, OperatorType.DIVIDE);
syntax.addTerminal("LPA", TokenType.OPERATOR, OperatorType.LPARAN);
syntax.addTerminal("RPA", TokenType.OPERATOR, OperatorType.RPARAN);
syntax.setEpsilonName("epsilon");
String[] nons = new String[] { "E", "E1", "T", "T1", "F", "A", "M" };
for (String non : nons) {
syntax.addNonTerminal(non);
}
syntax.infer("E -> T E1");
syntax.infer("E1 -> A T E1 | @epsilon");
syntax.infer("T -> F T1");
syntax.infer("T1 -> M F T1 | @epsilon");
syntax.infer("F -> @LPA E @RPA | @SYMBOL");
syntax.infer("A -> @PLUS | @MINUS");
syntax.infer("M -> @TIMES | @DIVIDE");
syntax.initialize("E");
System.out.println(syntax.toString());
// scanner.close();
} catch (RegexException e) {
System.err.println(e.getPosition() + "," + e.getMessage());
e.printStackTrace();
} catch (SyntaxException e) {
System.err.println(e.getPosition() + "," + e.getMessage() + " " + e.getInfo());
e.printStackTrace();
}
}
use of priv.bajdcc.LL1.syntax.handler.SyntaxException in project jMiniLang by bajdcc.
the class Syntax method doTail.
/**
* 处理右端表达式
*
* @throws SyntaxException 词法错误
*/
private void doTail() throws SyntaxException {
/* 获得分析后的表达式根结点 */
ISyntaxComponent exp = doAnalysis(TokenType.EOF, null);
/* 将根结点添加进对应规则 */
RuleItem item = new RuleItem(exp, rule.rule);
onAddRuleItem(item);
rule.rule.arrRules.add(item);
}
use of priv.bajdcc.LL1.syntax.handler.SyntaxException in project jMiniLang by bajdcc.
the class Syntax method setEpsilonName.
/**
* 定义空串名
*
* @param name
* 空串名称
* @throws SyntaxException 词法错误
*/
public void setEpsilonName(String name) throws SyntaxException {
TokenExp exp = new TokenExp(arrTerminals.size(), name, priv.bajdcc.util.lexer.token.TokenType.EOF, null);
if (!mapTerminals.containsKey(name)) {
epsilonName = name;
mapTerminals.put(name, exp);
arrTerminals.add(exp);
} else {
err(SyntaxError.REDECLARATION);
}
}
use of priv.bajdcc.LL1.syntax.handler.SyntaxException in project jMiniLang by bajdcc.
the class Syntax method buildFirstAndFollow.
/**
* 构造First集和Follow集
*
* @throws SyntaxException 词法错误
*/
private void buildFirstAndFollow() throws SyntaxException {
/* 非终结符数量 */
int size = arrNonTerminals.size();
/* 计算规则的First集合 */
boolean update;
do {
update = false;
for (RuleExp exp : arrNonTerminals) {
for (RuleItem item : exp.rule.arrRules) {
FirstSetSolver solver = new FirstSetSolver();
// 计算规则的First集合
item.expression.visit(solver);
item.epsilon = solver.solve(item);
if (item.epsilon && !exp.rule.epsilon) {
exp.rule.epsilon = true;
update = true;
}
}
}
} while (update);
/* 建立连通矩阵 */
// First集依赖矩阵
BitVector2 firstsetDependency = new BitVector2(size, size);
firstsetDependency.clear();
/* 计算非终结符First集合包含关系的布尔连通矩阵 */
{
int i = 0;
for (RuleExp exp : arrNonTerminals) {
for (RuleItem item : exp.rule.arrRules) {
for (RuleExp rule : item.setFirstSetRules) {
firstsetDependency.set(i, rule.id);
}
}
i++;
}
}
/* 检查间接左递归 */
{
/* 标记直接左递归 */
for (int i = 0; i < size; i++) {
if (firstsetDependency.test(i, i)) {
// 出现直接左递归
err(SyntaxError.DIRECT_RECURSION, arrNonTerminals.get(i).name);
}
}
/* 获得拷贝 */
BitVector2 a = (BitVector2) firstsetDependency.clone();
BitVector2 b = (BitVector2) firstsetDependency.clone();
BitVector2 r = new BitVector2(size, size);
/* 检查是否出现环 */
for (int level = 2; level < size; level++) {
/* 进行布尔连通矩阵乘法,即r=aXb */
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
r.clear(i, j);
for (int k = 0; k < size; k++) {
boolean value = r.test(i, j) || (a.test(i, k) && b.test(k, j));
r.set(i, j, value);
}
}
}
/* 检查当前结果是否出现环 */
{
int i = 0;
for (RuleExp exp : arrNonTerminals) {
if (r.test(i, i)) {
if (exp.rule.iRecursiveLevel < 2) {
exp.rule.iRecursiveLevel = level;
}
}
i++;
}
}
/* 保存结果 */
a = (BitVector2) r.clone();
}
/* 检查是否存在环并报告错误 */
for (RuleExp exp : arrNonTerminals) {
if (exp.rule.iRecursiveLevel > 1) {
err(SyntaxError.INDIRECT_RECURSION, exp.name + " level:" + exp.rule.iRecursiveLevel);
}
}
}
/* 建立规则的依赖关系 */
ArrayList<Integer> nodependencyList = new ArrayList<>();
{
/* 建立处理标记表 */
BitSet processed = new BitSet(size);
processed.clear();
/* 寻找First集的依赖关系 */
for (RuleExp arrNonTerminal : arrNonTerminals) {
/* 找出一条无最左依赖的规则 */
// 最左依赖的规则索引
int nodependencyRule = -1;
for (int j = 0; j < size; j++) {
if (!processed.get(j)) {
boolean empty = true;
for (int k = 0; k < size; k++) {
if (firstsetDependency.test(j, k)) {
empty = false;
break;
}
}
if (empty) {
// 找到
nodependencyRule = j;
break;
}
}
}
if (nodependencyRule == -1) {
err(SyntaxError.MISS_NODEPENDENCY_RULE, arrNonTerminal.name);
}
/* 清除该规则 */
processed.set(nodependencyRule);
for (int j = 0; j < size; j++) {
firstsetDependency.clear(j, nodependencyRule);
}
nodependencyList.add(nodependencyRule);
}
}
for (int nodependencyRule : nodependencyList) {
/* 计算该规则的终结符First集合 */
Rule rule = arrNonTerminals.get(nodependencyRule).rule;
/* 计算规则的终结符First集合 */
for (RuleItem item : rule.arrRules) {
for (RuleExp exp : item.setFirstSetRules) {
item.setFirstSetTokens.addAll(exp.rule.arrFirsts);
}
}
/* 计算非终结符的终结符First集合 */
for (RuleItem item : rule.arrRules) {
rule.arrFirsts.addAll(item.setFirstSetTokens);
}
}
/* 搜索不能产生字符串的规则 */
for (RuleExp exp : arrNonTerminals) {
for (RuleItem item : exp.rule.arrRules) {
if (item.setFirstSetTokens.isEmpty()) {
err(SyntaxError.FAILED, getSingleString(exp.name, item.expression));
}
}
}
/* 求Follow集 */
mapNonTerminals.get(beginRuleName).rule.setFollows.add(mapTerminals.get(epsilonName));
do {
update = false;
for (RuleExp origin : arrNonTerminals) {
for (RuleItem item : origin.rule.arrRules) {
for (RuleExp target : arrNonTerminals) {
FollowSetSolver solver = new FollowSetSolver(origin, target);
if (origin.name.equals("E1") && target.name.equals("T")) {
update = !!update;
}
item.expression.visit(solver);
update |= solver.isUpdated();
}
}
}
} while (update);
/* 将哈希表按ID排序并保存 */
for (RuleExp exp : arrNonTerminals) {
for (RuleItem item : exp.rule.arrRules) {
item.arrFirstSetTokens = sortTerminal(item.setFirstSetTokens);
item.parent.arrFollows = sortTerminal(item.parent.setFollows);
}
}
}
use of priv.bajdcc.LL1.syntax.handler.SyntaxException in project jMiniLang by bajdcc.
the class Syntax method addTerminal.
/**
* 添加终结符
*
* @param name
* 终结符名称
* @param type
* 单词类型
* @param obj
* 单词信息
* @throws SyntaxException 词法错误
*/
public void addTerminal(String name, priv.bajdcc.util.lexer.token.TokenType type, Object obj) throws SyntaxException {
TokenExp exp = new TokenExp(arrTerminals.size(), name, type, obj);
if (!mapTerminals.containsKey(name)) {
mapTerminals.put(name, exp);
arrTerminals.add(exp);
} else {
err(SyntaxError.REDECLARATION);
}
}
Aggregations