Search in sources :

Example 1 with RuleItem

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

the class Semantic method run.

/**
 * 进行语义处理
 */
private void run() throws SyntaxException {
    if (!arrErrors.isEmpty()) {
        System.err.println(getTrackerError());
        throw new SyntaxException(SyntaxError.COMPILE_ERROR, arrErrors.get(0).position, "出现语法错误");
    }
    /* 规则集合 */
    ArrayList<RuleItem> items = npa.getRuleItems();
    /* 符号表查询接口 */
    IQuerySymbol query = getQuerySymbolService();
    /* 符号表管理接口 */
    IManageSymbol manage = getManageSymbolService();
    /* 语义错误处理接口 */
    ISemanticRecorder recorder = getSemanticRecorderService();
    /* 复制单词流 */
    ArrayList<Token> tokens = arrTokens.stream().map(Token::copy).collect(Collectors.toCollection(ArrayList::new));
    /* 运行时自动机 */
    SemanticMachine machine = new SemanticMachine(items, arrActions, tokens, query, manage, recorder, debug);
    /* 遍历所有指令 */
    arrInsts.forEach(machine::run);
    object = machine.getObject();
    if (object != null) {
        Function entry = (Function) object;
        manage.getManageScopeService().registerFunc(entry);
    }
}
Also used : Function(priv.bajdcc.LALR1.grammar.tree.Function) SyntaxException(priv.bajdcc.LALR1.syntax.handler.SyntaxException) RuleItem(priv.bajdcc.LALR1.syntax.rule.RuleItem) IManageSymbol(priv.bajdcc.LALR1.grammar.symbol.IManageSymbol) Token(priv.bajdcc.util.lexer.token.Token) IQuerySymbol(priv.bajdcc.LALR1.grammar.symbol.IQuerySymbol) ISemanticRecorder(priv.bajdcc.LALR1.grammar.semantic.ISemanticRecorder)

Example 2 with RuleItem

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

the class Semantic method getTrackerStatus.

/**
 * 获取跟踪器信息
 */
private String getTrackerStatus() {
    /* 用于调试 */
    System.err.println("#### #### ####");
    System.err.println(tracker.iter.index());
    System.err.println(tracker.iter.position());
    System.err.println(tracker.npaStatus.data.label);
    ArrayList<RuleItem> items = npa.getRuleItems();
    StringBuilder sb = new StringBuilder();
    sb.append(System.lineSeparator());
    InstructionRecord rcd = tracker.rcdInst;
    while (rcd != null) {
        for (Instruction inst : rcd.arrInsts) {
            sb.append(inst.toString());
            if (inst.iHandler != -1) {
                RuleItem item = items.get(inst.iHandler);
                sb.append("\t").append(getSingleString(item.parent.nonTerminal.name, item.expression));
            }
            sb.append(System.lineSeparator());
        }
        rcd = rcd.prev;
        sb.append(System.lineSeparator());
    }
    return sb.toString();
}
Also used : RuleItem(priv.bajdcc.LALR1.syntax.rule.RuleItem)

Example 3 with RuleItem

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

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

Example 5 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(strBeginRuleName);
    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.setFirstSetTokens) {
                sb.append("\t\t").append(token.name);
                sb.append(System.lineSeparator());
            }
            sb.append("\t--== 非终结符First集合 ==--");
            sb.append(System.lineSeparator());
            for (RuleExp rule : item.setFirstSetRules) {
                sb.append("\t\t").append(rule.name);
                sb.append(System.lineSeparator());
            }
        }
    }
    return sb.toString();
}
Also used : RuleExp(priv.bajdcc.LALR1.syntax.exp.RuleExp) RuleItem(priv.bajdcc.LALR1.syntax.rule.RuleItem) TokenExp(priv.bajdcc.LALR1.syntax.exp.TokenExp)

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