Search in sources :

Example 6 with RuleItem

use of priv.bajdcc.LL1.syntax.rule.RuleItem in project jMiniLang by bajdcc.

the class Syntax method semanticAnalysis.

/**
 * 进行语义分析
 *
 * @throws SyntaxException 词法错误
 */
private void semanticAnalysis() throws SyntaxException {
    /* 非终结符数量 */
    int size = arrNonTerminals.size();
    /* 计算规则的First集合 */
    for (RuleExp exp : arrNonTerminals) {
        for (RuleItem item : exp.rule.arrRules) {
            FirstsetSolver solver = new FirstsetSolver();
            // 计算规则的First集合
            item.expression.visit(solver);
            if (!solver.solve(item)) {
                // 若串长度可能为零,即产生空串
                err(SyntaxError.EPSILON, getSingleString(exp.name, item.expression));
            }
        }
    }
    /* 建立连通矩阵 */
    // 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)) {
                // 直接左递归
                arrNonTerminals.get(i).rule.iRecursiveLevel = 1;
                firstsetDependency.clear(i, i);
            }
        }
        /* 获得拷贝 */
        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);
            }
        }
    }
    /* 计算完整的First集合 */
    {
        /* 建立处理标记表 */
        BitSet processed = new BitSet(size);
        processed.clear();
        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);
            }
            /* 计算该规则的终结符First集合 */
            {
                Rule rule = arrNonTerminals.get(nodependencyRule).rule;
                /* 计算规则的终结符First集合 */
                for (RuleItem item : rule.arrRules) {
                    for (RuleExp exp : item.setFirstSetRules) {
                        item.setFirstSetTokens.addAll(exp.rule.arrTokens);
                    }
                }
                /* 计算非终结符的终结符First集合 */
                for (RuleItem item : rule.arrRules) {
                    rule.arrTokens.addAll(item.setFirstSetTokens);
                }
                /* 修正左递归规则的终结符First集合 */
                for (RuleItem item : rule.arrRules) {
                    if (item.setFirstSetRules.contains(arrNonTerminals.get(nodependencyRule))) {
                        item.setFirstSetTokens.addAll(rule.arrTokens);
                    }
                }
            }
            /* 清除该规则 */
            processed.set(nodependencyRule);
            for (int j = 0; j < size; j++) {
                firstsetDependency.clear(j, nodependencyRule);
            }
        }
    }
    /* 搜索不能产生字符串的规则 */
    for (RuleExp exp : arrNonTerminals) {
        for (RuleItem item : exp.rule.arrRules) {
            if (item.setFirstSetTokens.isEmpty()) {
                err(SyntaxError.FAILED, getSingleString(exp.name, item.expression));
            }
        }
    }
}
Also used : BitVector2(priv.bajdcc.util.BitVector2) RuleExp(priv.bajdcc.LALR1.syntax.exp.RuleExp) RuleItem(priv.bajdcc.LALR1.syntax.rule.RuleItem) BitSet(java.util.BitSet) Rule(priv.bajdcc.LALR1.syntax.rule.Rule) FirstsetSolver(priv.bajdcc.LALR1.syntax.solver.FirstsetSolver)

Example 7 with RuleItem

use of priv.bajdcc.LL1.syntax.rule.RuleItem in project jMiniLang by bajdcc.

the class NGA method generateNGAMap.

/**
 * 产生NGA映射表
 */
private void generateNGAMap() {
    int j = 0;
    for (RuleExp exp : arrNonTerminals) {
        j++;
        int i = 0;
        j = j + i - i;
        for (RuleItem item : exp.rule.arrRules) {
            /* 表达式转换成NGA */
            bag = new NGABag();
            bag.expression = item.expression;
            bag.prefix = exp.name + "[" + i + "]";
            bag.expression.visit(this);
            ENGA enga = bag.nga;
            /* NGA去Epsilon边 */
            NGAStatus status = deleteEpsilon(enga);
            /* 保存 */
            mapNGA.put(item, status);
            i++;
        }
    }
}
Also used : RuleExp(priv.bajdcc.LALR1.syntax.exp.RuleExp) RuleItem(priv.bajdcc.LALR1.syntax.rule.RuleItem)

Example 8 with RuleItem

use of priv.bajdcc.LL1.syntax.rule.RuleItem in project jMiniLang by bajdcc.

the class Syntax method getParagraphString.

/**
 * 获得段落式描述
 * @return 段落式描述
 */
public String getParagraphString() {
    StringBuilder sb = new StringBuilder();
    /* 起始符号 */
    sb.append("#### 起始符号 ####");
    sb.append(System.lineSeparator());
    sb.append(beginRuleName);
    sb.append(System.lineSeparator());
    /* 终结符 */
    sb.append("#### 终结符 ####");
    sb.append(System.lineSeparator());
    for (TokenExp exp : arrTerminals) {
        sb.append(exp.toString());
        sb.append(System.lineSeparator());
    }
    /* 非终结符 */
    sb.append("#### 非终结符 ####");
    sb.append(System.lineSeparator());
    for (RuleExp exp : arrNonTerminals) {
        sb.append(exp.toString());
        sb.append(System.lineSeparator());
    }
    /* 推导规则 */
    sb.append("#### 文法产生式 ####");
    sb.append(System.lineSeparator());
    for (RuleExp exp : arrNonTerminals) {
        for (RuleItem item : exp.rule.arrRules) {
            /* 规则正文 */
            sb.append(getSingleString(exp.name, item.expression));
            sb.append(System.lineSeparator());
            /* First集合 */
            sb.append("\t--== First ==--");
            sb.append(System.lineSeparator());
            for (TokenExp token : item.arrFirstSetTokens) {
                sb.append("\t\t").append(token.toString());
                sb.append(System.lineSeparator());
            }
            sb.append("\t--== Follow ==--");
            sb.append(System.lineSeparator());
            for (TokenExp token : item.parent.arrFollows) {
                sb.append("\t\t").append(token.toString());
                sb.append(System.lineSeparator());
            }
        }
    }
    return sb.toString();
}
Also used : RuleExp(priv.bajdcc.LL1.syntax.exp.RuleExp) RuleItem(priv.bajdcc.LL1.syntax.rule.RuleItem) TokenExp(priv.bajdcc.LL1.syntax.exp.TokenExp)

Example 9 with RuleItem

use of priv.bajdcc.LL1.syntax.rule.RuleItem in project jMiniLang by bajdcc.

the class Syntax method getOriginalString.

/**
 * 获得原推导式描述
 * @return 原推导式描述
 */
public String getOriginalString() {
    StringBuilder sb = new StringBuilder();
    for (RuleExp exp : arrNonTerminals) {
        for (RuleItem item : exp.rule.arrRules) {
            sb.append(getSingleString(exp.name, item.expression));
            sb.append(System.lineSeparator());
        }
    }
    return sb.toString();
}
Also used : RuleExp(priv.bajdcc.LL1.syntax.exp.RuleExp) RuleItem(priv.bajdcc.LL1.syntax.rule.RuleItem)

Example 10 with RuleItem

use of priv.bajdcc.LL1.syntax.rule.RuleItem in project jMiniLang by bajdcc.

the class PredictionTable method predict.

/**
 * 构造预测分析表
 */
private void predict() {
    for (RuleExp exp : arrNonTerminals) {
        indexVn++;
        for (RuleItem item : exp.rule.arrRules) {
            this.item = item;
            item.expression.visit(this);
        }
    }
}
Also used : RuleExp(priv.bajdcc.LL1.syntax.exp.RuleExp) RuleItem(priv.bajdcc.LL1.syntax.rule.RuleItem)

Aggregations

RuleItem (priv.bajdcc.LALR1.syntax.rule.RuleItem)9 RuleExp (priv.bajdcc.LALR1.syntax.exp.RuleExp)5 RuleItem (priv.bajdcc.LL1.syntax.rule.RuleItem)5 RuleExp (priv.bajdcc.LL1.syntax.exp.RuleExp)4 ArrayList (java.util.ArrayList)2 BitSet (java.util.BitSet)2 TokenExp (priv.bajdcc.LALR1.syntax.exp.TokenExp)2 Rule (priv.bajdcc.LALR1.syntax.rule.Rule)2 BitVector2 (priv.bajdcc.util.BitVector2)2 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Iterator (java.util.Iterator)1 Entry (java.util.Map.Entry)1 Collectors (java.util.stream.Collectors)1 ISemanticRecorder (priv.bajdcc.LALR1.grammar.semantic.ISemanticRecorder)1 IManageSymbol (priv.bajdcc.LALR1.grammar.symbol.IManageSymbol)1 IQuerySymbol (priv.bajdcc.LALR1.grammar.symbol.IQuerySymbol)1 Function (priv.bajdcc.LALR1.grammar.tree.Function)1 ISemanticAction (priv.bajdcc.LALR1.semantic.token.ISemanticAction)1 NGA (priv.bajdcc.LALR1.syntax.automata.nga.NGA)1