Search in sources :

Example 1 with Rule

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

the class NPA method generateNPA.

/**
 * 产生下推自动机
 */
private void generateNPA() {
    /* 下推自动机状态 */
    ArrayList<NPAStatus> NPAStatusList = new ArrayList<>();
    /* 文法自动机状态 */
    ArrayList<NGAStatus> NGAStatusList = new ArrayList<>();
    /* 下推自动机边(规则映射到NGA边) */
    HashMap<Rule, ArrayList<NGAEdge>> ruleEdgeMap = new HashMap<>();
    /* 遍历每条规则 */
    for (Entry<RuleItem, NGAStatus> entry : mapNGA.entrySet()) {
        RuleItem key = entry.getKey();
        NGAStatus value = entry.getValue();
        /* 保存规则 */
        arrRuleItems.add(key);
        /* 搜索当前规则中的所有状态 */
        ArrayList<NGAStatus> CurrentNGAStatusList = getNGAStatusClosure(new BreadthFirstSearch<>(), value);
        /* 搜索所有的边 */
        for (NGAStatus status : CurrentNGAStatusList) {
            /* 若边为非终结符边,则加入邻接表,终结符->带终结符的所有边 */
            status.outEdges.stream().filter(edge -> edge.data.kAction == NGAEdgeType.RULE).forEach(edge -> {
                Rule rule = edge.data.rule.rule;
                if (!ruleEdgeMap.containsKey(rule)) {
                    ruleEdgeMap.put(rule, new ArrayList<>());
                }
                ruleEdgeMap.get(rule).add(edge);
            });
        }
        /* 为所有的NGA状态构造对应的NPA状态,为一一对应 */
        for (NGAStatus status : CurrentNGAStatusList) {
            /* 保存NGA状态 */
            NGAStatusList.add(status);
            /* 新建NPA状态 */
            NPAStatus NPAStatus = new NPAStatus();
            NPAStatus.data.label = status.data.label;
            NPAStatus.data.iRuleItem = arrRuleItems.indexOf(key);
            NPAStatusList.add(NPAStatus);
        }
    }
    /* 遍历所有NPA状态 */
    for (int i = 0; i < NPAStatusList.size(); i++) {
        /* 获得NGA状态 */
        NGAStatus ngaStatus = NGAStatusList.get(i);
        /* 获得NPA状态 */
        NPAStatus npaStatus = NPAStatusList.get(i);
        /* 获得规则 */
        RuleItem ruleItem = arrRuleItems.get(npaStatus.data.iRuleItem);
        /* 检查是否为纯左递归,类似[A::=Aa]此类,无法直接添加纯左递归边,需要LA及归约 */
        if (!isLeftRecursiveStatus(ngaStatus, ruleItem.parent)) {
            /* 当前状态是否为初始状态且推导规则是否属于起始规则(无NGA入边) */
            boolean isInitRuleStatus = initRule == ruleItem.parent;
            /* 若是,则将当前状态对应的NPA状态加入初始状态表中 */
            if (ngaStatus.inEdges.isEmpty() && isInitRuleStatus) {
                arrInitStatusList.add(npaStatus);
            }
            /* 建立计算优先级使用的记号表,其中元素为从当前状态出发的Rule或Token边的First集(LA预查优先) */
            HashSet<Integer> tokenSet = new HashSet<>();
            /* 遍历文法自动机的所有边 */
            for (NGAEdge edge : ngaStatus.outEdges) {
                switch(edge.data.kAction) {
                    case EPSILON:
                        break;
                    case RULE:
                        /* 判断边是否为纯左递归 */
                        if (!isLeftRecursiveEdge(edge, ruleItem.parent)) {
                            for (RuleItem item : edge.data.rule.rule.arrRules) {
                                /* 起始状态 */
                                NGAStatus initItemStatus = mapNGA.get(item);
                                /* 判断状态是否为纯左递归 */
                                if (!isLeftRecursiveStatus(initItemStatus, item.parent)) {
                                    /* 添加Shift边,功能为将一条状态序号放入堆栈顶 */
                                    NPAEdge npaEdge = connect(npaStatus, NPAStatusList.get(NGAStatusList.indexOf(initItemStatus)));
                                    npaEdge.data.handler = edge.data.handler;
                                    npaEdge.data.action = edge.data.action;
                                    npaEdge.data.kAction = NPAEdgeType.SHIFT;
                                    npaEdge.data.inst = NPAInstruction.SHIFT;
                                    npaEdge.data.errorJump = NPAStatusList.get(NGAStatusList.indexOf(edge.end));
                                    /* 为移进项目构造LookAhead表,LA不吃字符,只是单纯压入新的状态(用于规约) */
                                    npaEdge.data.arrLookAhead = new HashSet<>();
                                    npaEdge.data.arrLookAhead.addAll(item.setFirstSetTokens.stream().filter(exp -> !tokenSet.contains(exp.id)).map(exp -> exp.id).collect(Collectors.toList()));
                                }
                            }
                            // 将当前非终结符的所有终结符First集加入tokenSet,以便非终结符的Move的LA操作(优先级)
                            tokenSet.addAll(edge.data.rule.rule.arrTokens.stream().map(exp -> exp.id).collect(Collectors.toList()));
                        }
                        break;
                    case TOKEN:
                        /* 添加Move边,功能为吃掉(匹配)一个终结符,若终结符不匹配,则报错(即不符合文法) */
                        NPAEdge npaEdge = connect(npaStatus, NPAStatusList.get(NGAStatusList.indexOf(edge.end)));
                        npaEdge.data.handler = edge.data.handler;
                        npaEdge.data.action = edge.data.action;
                        npaEdge.data.kAction = NPAEdgeType.MOVE;
                        npaEdge.data.iToken = edge.data.token.id;
                        npaEdge.data.iHandler = arrActions.indexOf(edge.data.action);
                        npaEdge.data.errorJump = npaEdge.end;
                        /* 根据StorageID配置指令 */
                        if (edge.data.iStorage != -1) {
                            npaEdge.data.inst = NPAInstruction.READ;
                            // 参数
                            npaEdge.data.iIndex = edge.data.iStorage;
                        } else {
                            npaEdge.data.inst = NPAInstruction.PASS;
                        }
                        /* 修改TokenSet */
                        if (tokenSet.contains(edge.data.token.id)) {
                            /* 使用LookAhead表 */
                            npaEdge.data.arrLookAhead = new HashSet<>();
                        } else {
                            tokenSet.add(edge.data.token.id);
                        }
                        break;
                    default:
                        break;
                }
            }
            /* 如果当前NGA状态是结束状态(此时要进行规约),则检查是否需要添加其他边 */
            if (ngaStatus.data.bFinal) {
                if (ruleEdgeMap.containsKey(ruleItem.parent)) {
                    /* 遍历文法自动机中附带了当前推导规则所属规则的边 */
                    ArrayList<NGAEdge> ruleEdges = ruleEdgeMap.get(// 当前规约的文法的非终结符为A,获得包含A的所有边
                    ruleItem.parent);
                    for (NGAEdge ngaEdge : ruleEdges) {
                        /* 判断纯左递归,冗长的表达式是为了获得当前边的所在推导式的起始非终结符 */
                        if (isLeftRecursiveEdge(ngaEdge, arrRuleItems.get(NPAStatusList.get(NGAStatusList.indexOf(ngaEdge.begin)).data.iRuleItem).parent)) {
                            /* 添加Left Recursion边(特殊的Reduce边) */
                            NPAEdge npaEdge = connect(npaStatus, NPAStatusList.get(NGAStatusList.indexOf(ngaEdge.end)));
                            npaEdge.data.kAction = NPAEdgeType.LEFT_RECURSION;
                            if (ngaEdge.data.iStorage != -1) {
                                npaEdge.data.inst = NPAInstruction.LEFT_RECURSION;
                                npaEdge.data.iIndex = ngaEdge.data.iStorage;
                            } else {
                                npaEdge.data.inst = NPAInstruction.LEFT_RECURSION_DISCARD;
                            }
                            // 规约的规则
                            npaEdge.data.iHandler = npaStatus.data.iRuleItem;
                            /* 为左递归构造Lookahead表(Follow集),若LA成功则进入左递归 */
                            npaEdge.data.arrLookAhead = new HashSet<>();
                            for (NGAEdge edge : ngaEdge.end.outEdges) {
                                /* 若出边为终结符,则直接加入(终结符First集仍是本身) */
                                if (edge.data.kAction == NGAEdgeType.TOKEN) {
                                    npaEdge.data.arrLookAhead.add(edge.data.token.id);
                                } else {
                                    /* 若出边为非终结符,则加入非终结符的First集 */
                                    npaEdge.data.arrLookAhead.addAll(edge.data.rule.rule.arrTokens.stream().map(exp -> exp.id).collect(Collectors.toList()));
                                }
                            }
                        } else {
                            /* 添加Reduce边 */
                            NPAEdge npaEdge = connect(npaStatus, NPAStatusList.get(NGAStatusList.indexOf(ngaEdge.end)));
                            npaEdge.data.kAction = NPAEdgeType.REDUCE;
                            npaEdge.data.status = NPAStatusList.get(NGAStatusList.indexOf(ngaEdge.begin));
                            if (ngaEdge.data.iStorage != -1) {
                                npaEdge.data.inst = NPAInstruction.TRANSLATE;
                                npaEdge.data.iIndex = ngaEdge.data.iStorage;
                            } else {
                                npaEdge.data.inst = NPAInstruction.TRANSLATE_DISCARD;
                            }
                            // 规约的规则
                            npaEdge.data.iHandler = npaStatus.data.iRuleItem;
                        }
                    }
                }
                if (isInitRuleStatus) {
                    /* 添加Finish边 */
                    NPAEdge npaEdge = connect(npaStatus, npaStatus);
                    npaEdge.data.kAction = NPAEdgeType.FINISH;
                    npaEdge.data.inst = NPAInstruction.TRANSLATE_FINISH;
                    npaEdge.data.iHandler = npaStatus.data.iRuleItem;
                }
            }
        }
    }
}
Also used : Iterator(java.util.Iterator) ISemanticAction(priv.bajdcc.LALR1.semantic.token.ISemanticAction) RuleItem(priv.bajdcc.LALR1.syntax.rule.RuleItem) HashMap(java.util.HashMap) Collectors(java.util.stream.Collectors) BreadthFirstSearch(priv.bajdcc.util.lexer.automata.BreadthFirstSearch) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) NGA(priv.bajdcc.LALR1.syntax.automata.nga.NGA) RuleExp(priv.bajdcc.LALR1.syntax.exp.RuleExp) NGAEdge(priv.bajdcc.LALR1.syntax.automata.nga.NGAEdge) NGAStatus(priv.bajdcc.LALR1.syntax.automata.nga.NGAStatus) TokenExp(priv.bajdcc.LALR1.syntax.exp.TokenExp) Entry(java.util.Map.Entry) Rule(priv.bajdcc.LALR1.syntax.rule.Rule) NGAEdgeType(priv.bajdcc.LALR1.syntax.automata.nga.NGAEdgeType) HashMap(java.util.HashMap) NGAEdge(priv.bajdcc.LALR1.syntax.automata.nga.NGAEdge) ArrayList(java.util.ArrayList) NGAStatus(priv.bajdcc.LALR1.syntax.automata.nga.NGAStatus) RuleItem(priv.bajdcc.LALR1.syntax.rule.RuleItem) Rule(priv.bajdcc.LALR1.syntax.rule.Rule) HashSet(java.util.HashSet)

Example 2 with Rule

use of priv.bajdcc.LL1.syntax.rule.Rule 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 3 with Rule

use of priv.bajdcc.LL1.syntax.rule.Rule 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)

Aggregations

ArrayList (java.util.ArrayList)2 BitSet (java.util.BitSet)2 RuleExp (priv.bajdcc.LALR1.syntax.exp.RuleExp)2 Rule (priv.bajdcc.LALR1.syntax.rule.Rule)2 RuleItem (priv.bajdcc.LALR1.syntax.rule.RuleItem)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 ISemanticAction (priv.bajdcc.LALR1.semantic.token.ISemanticAction)1 NGA (priv.bajdcc.LALR1.syntax.automata.nga.NGA)1 NGAEdge (priv.bajdcc.LALR1.syntax.automata.nga.NGAEdge)1 NGAEdgeType (priv.bajdcc.LALR1.syntax.automata.nga.NGAEdgeType)1 NGAStatus (priv.bajdcc.LALR1.syntax.automata.nga.NGAStatus)1 TokenExp (priv.bajdcc.LALR1.syntax.exp.TokenExp)1 FirstsetSolver (priv.bajdcc.LALR1.syntax.solver.FirstsetSolver)1 RuleExp (priv.bajdcc.LL1.syntax.exp.RuleExp)1 Rule (priv.bajdcc.LL1.syntax.rule.Rule)1