Search in sources :

Example 21 with SyntaxException

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();
    }
}
Also used : SyntaxException(priv.bajdcc.LL1.syntax.handler.SyntaxException) RegexException(priv.bajdcc.util.lexer.error.RegexException) Syntax(priv.bajdcc.LL1.syntax.Syntax)

Example 22 with SyntaxException

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);
}
Also used : RuleItem(priv.bajdcc.LL1.syntax.rule.RuleItem)

Example 23 with SyntaxException

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);
    }
}
Also used : TokenExp(priv.bajdcc.LL1.syntax.exp.TokenExp)

Example 24 with SyntaxException

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);
        }
    }
}
Also used : BitVector2(priv.bajdcc.util.BitVector2) RuleExp(priv.bajdcc.LL1.syntax.exp.RuleExp) RuleItem(priv.bajdcc.LL1.syntax.rule.RuleItem) ArrayList(java.util.ArrayList) BitSet(java.util.BitSet) FirstSetSolver(priv.bajdcc.LL1.syntax.solver.FirstSetSolver) Rule(priv.bajdcc.LL1.syntax.rule.Rule) FollowSetSolver(priv.bajdcc.LL1.syntax.solver.FollowSetSolver)

Example 25 with SyntaxException

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);
    }
}
Also used : TokenExp(priv.bajdcc.LL1.syntax.exp.TokenExp)

Aggregations

RegexException (priv.bajdcc.util.lexer.error.RegexException)27 SyntaxException (priv.bajdcc.LALR1.syntax.handler.SyntaxException)26 Grammar (priv.bajdcc.LALR1.grammar.Grammar)17 RuntimeCodePage (priv.bajdcc.LALR1.grammar.runtime.RuntimeCodePage)15 RuntimeException (priv.bajdcc.LALR1.grammar.runtime.RuntimeException)15 ByteArrayInputStream (java.io.ByteArrayInputStream)13 ByteArrayOutputStream (java.io.ByteArrayOutputStream)13 Interpreter (priv.bajdcc.LALR1.interpret.Interpreter)13 Semantic (priv.bajdcc.LALR1.semantic.Semantic)5 Syntax (priv.bajdcc.LALR1.syntax.Syntax)3 RuntimeMachine (priv.bajdcc.LALR1.grammar.runtime.RuntimeMachine)2 ISemanticAnalyzer (priv.bajdcc.LALR1.semantic.token.ISemanticAnalyzer)2 Grammar (priv.bajdcc.LL1.grammar.Grammar)2 GrammarException (priv.bajdcc.LL1.grammar.error.GrammarException)2 TokenExp (priv.bajdcc.LL1.syntax.exp.TokenExp)2 SyntaxException (priv.bajdcc.LL1.syntax.handler.SyntaxException)2 RuleItem (priv.bajdcc.LL1.syntax.rule.RuleItem)2 TokenType (priv.bajdcc.util.lexer.token.TokenType)2 BufferedReader (java.io.BufferedReader)1 FileReader (java.io.FileReader)1