Esempio n. 1
0
        /// <summary>
        /// 将正则表达式转换为 NFA。
        /// </summary>
        /// <param name="grammar">语法分析的语法。</param>
        /// <param name="useTrailing">是否使用了向前看符号。</param>
        /// <returns>构造得到的 NFA。</returns>
        private static Nfa BuildNfa(Grammar <T> grammar, out bool useTrailing)
        {
            int contextCnt = grammar.Contexts.Count;
            // 将多个上下文的规则放入一个 NFA 中,但起始状态不同。
            Nfa nfa = new Nfa();

            for (int i = 0; i < contextCnt; i++)
            {
                // 为每个上下文创建自己的起始状态,普通规则的起始状态。
                nfa.NewState();
                // 行首规则的起始状态。
                nfa.NewState();
            }
            useTrailing = false;
            foreach (Terminal <T> sym in grammar.Terminals)
            {
                if (sym.RegularExpression is EndOfFileExp)
                {
                    continue;
                }
                sym.RegularExpression.BuildNfa(nfa);
                nfa.TailState.SymbolIndex = sym.Index;
                // 是否是行首限定的。
                bool      isBeginningOfLine = false;
                AnchorExp anchorExp         = sym.RegularExpression as AnchorExp;
                if (anchorExp != null)
                {
                    if (anchorExp.BeginningOfLine)
                    {
                        isBeginningOfLine = true;
                    }
                    if (anchorExp.TrailingHeadState != null)
                    {
                        // 设置向前看状态类型。
                        anchorExp.TrailingHeadState.SymbolIndex = sym.Index;
                        useTrailing = true;
                    }
                }
                foreach (LexerContext context in sym.Context)
                {
                    if (isBeginningOfLine)
                    {
                        // 行首限定规则。
                        nfa[context.Index * 2 + 1].Add(nfa.HeadState);
                    }
                    else
                    {
                        // 普通规则。
                        nfa[context.Index * 2].Add(nfa.HeadState);
                        nfa[context.Index * 2 + 1].Add(nfa.HeadState);
                    }
                }
            }
            return(nfa);
        }
Esempio n. 2
0
        /// <summary>
        /// 填充行首匹配和向前看的数据。
        /// </summary>
        /// <param name="grammar">词法分析器使用的语法。</param>
        private void FillTrailing(Grammar <T> grammar)
        {
            bool variableTrailing = false;

            this.containsBeginningOfLineRule = false;
            foreach (Terminal <T> sym in grammar.Terminals)
            {
                AnchorExp exp = sym.RegularExpression as AnchorExp;
                if (exp != null)
                {
                    if (exp.BeginningOfLine == true)
                    {
                        this.containsBeginningOfLineRule = true;
                    }
                    if (exp.TrailingExpression != null)
                    {
                        int len = exp.TrailingExpression.Length;
                        if (len != -1)
                        {
                            this.symbols[sym.Index].Trailing = -len;
                        }
                        else
                        {
                            len = exp.InnerExpression.Length;
                            if (len != -1)
                            {
                                this.symbols[sym.Index].Trailing = len;
                            }
                            else
                            {
                                this.symbols[sym.Index].Trailing = 0;
                                variableTrailing = true;
                            }
                        }
                    }
                }
            }
            if (variableTrailing)
            {
                this.trailingType = TrailingType.Variable;
            }
            else
            {
                this.trailingType = TrailingType.Fixed;
            }
        }