Example #1
0
        /// <summary>
        /// 解释器核心运行
        /// 包括调用词法、语法、语义分析
        /// 以及出错处理程序
        /// </summary>
        /// <param name="bpList">breakPoint列表,所有断点所在行数</param>
        public InterpretResult Run(List <int> bpList)
        {
            // 解释器最终结果
            InterpretResult result = new InterpretResult();

            // 词法分析
            TokenResult tokenResult = WordAnalyse();

            result.WordAnalyseResult = tokenResult;
            result.Period            = InterpretPeriod.Word;
            if (!tokenResult.IsSuccess)
            {
                // 如果词法分析失败,则给出失败原因
                result.IsSuccess  = false;
                result.ErrorInfos = tokenResult.ErrorInfos;

                return(result);
            }

            // 语法分析
            this.syntacticAnalyser = new SyntacticAnalyser();
            ParseTree parseTree = SyntacticAnalyse(tokenResult, bpList);

            result.SyntacticAnalyseResult = parseTree;
            result.Period = InterpretPeriod.Syntactic;
            if (!parseTree.IsSuccess)
            {
                result.IsSuccess  = false;
                result.ErrorInfos = parseTree.ErrorInfos;

                return(result);
            }

            return(result);
        }
        /// <summary>
        /// 当前用户输入的所有变量
        /// </summary>
        /// <param name="inputStr"></param>
        /// <returns></returns>
        public static List <string> GetAllVariables(string inputStr)
        {
            // 用于接收结果的string
            List <string> variables = new List <string>();

            TokenResult  result = Analyse(inputStr);
            List <Token> tokens = result.Tokens;

            tokens.RemoveAt(tokens.Count - 1);
            if (tokens.Count > 0)
            {
                tokens.RemoveAt(tokens.Count - 1);
            }

            for (int i = 0; i < tokens.Count; i++)
            {
                if (tokens[i].TokenType == TerminalType.ID)
                {
                    variables.Add(tokens[i].StrValue);
                }
            }

            return(variables);
        }
        /// <summary>
        /// 词法分析程序主体
        /// </summary>
        /// <param name="inputStr">要分析的文本</param>
        /// <returns>词法分析结果</returns>
        public static TokenResult Analyse(string inputStr)
        {
            if (inputStr == null || inputStr == "")
            {
                return(new TokenResult());
            }
            input  = inputStr;
            index  = 0;
            line   = 1;
            buffer = "";
            ch     = input[index];

            isAnalysing = true;
            result      = new TokenResult();

            while (isAnalysing)
            {
                Concat();
                try
                {
                    if (Array.IndexOf(symbols, buffer) != -1)
                    {
                        AnalyseSymbol();
                    }
                    else if (Char.IsDigit(ch))
                    {
                        AnalyseNumber();
                    }
                    else if (Char.IsLetter(ch) || ch == '_')
                    {
                        AnalyseIdAndKey();
                    }
                    else if (Char.IsWhiteSpace(ch))
                    {
                        AnalyseRow();
                    }
                    else
                    {
                        throw new Exception("符号错误:未知符号");
                    }
                }
                catch (Exception ex)
                {
                    error = new ErrorInfo(line, ex.Message);
                    result.ErrorInfos.Add(error);
                }
                finally
                {
                    Peek();
                }
            }

            // 添加结束符
            buffer = "$";
            value  = TerminalType.END;
            Read();

            result.IsSuccess = result.ErrorInfos.Count == 0;

            return(result);
        }
Example #4
0
        /// <summary>
        /// 利用词法分析的结果进行语法分析
        /// </summary>
        /// <param name="tokenResult">由词法分析得到的token结果</param>
        /// <param name="bpList">断点行号列表</param>
        /// <returns>语法分析树</returns>
        public ParseTree SyntacticAnalysis(TokenResult tokenResult, List <int> bpList)
        {
            #region 语法分析初始化

            // 初始化断点列表
            this.bPLineNums = bpList;

            this.targetTree.IsSuccess = true;                          // 表示语法分析是否成功
            List <ErrorInfo> totalErrorInfos = new List <ErrorInfo>(); // 总的报错信息

            // 将所有token读入栈
            for (int i = tokenResult.Tokens.Count - 1; i >= 0; i--)
            {
                if (tokenResult.Tokens[i].TokenType != TerminalType.NOTES)
                {
                    inputStack.Push(tokenResult.Tokens[i]);
                }
            }

            // 将结束符号放入符号栈中
            ParseTreeNode EndNode = new ParseTreeNode(true, TerminalType.END, NEnum.DEFAULT);
            symbolStack.Push(EndNode);

            // 将program放入符号栈
            symbolStack.Push(targetTree.Root);

            #endregion

            #region 语法分析主体程序
            // 每次从输入栈中读取一个符号并更新符号栈的值
            // 当没有读到$时进行循环,如果下一个是结束符号$则结束循环
            Token         token;      // 输入串中的当前讨论的token
            ParseTreeNode symbolNode; // 符号表中当前讨论的结点

            while (inputStack.Count > 0 && symbolStack.Count > 0)
            {
                token      = inputStack.Peek();
                symbolNode = symbolStack.Peek();

                // 遇到注释则跳过
                if (symbolNode.TSymbol == TerminalType.NOTES)
                {
                    continue;
                }

                #region 特殊非终结符号处理
                // 遇到标识符特殊考虑
                List <ErrorInfo> variableErrorInfos, expErrorInfos;
                if (symbolNode.NSymbol == NEnum.variable)
                {
                    this.VariableAnalyse(symbolNode, out variableErrorInfos);
                    totalErrorInfos.AddRange(variableErrorInfos);
                    continue;
                }

                // 遇到表达式特殊考虑
                if (symbolNode.NSymbol == NEnum.exp)
                {
                    this.ExpAnalyse(symbolNode, out expErrorInfos);
                    // 将exp出栈
                    PopSymbolStack();
                    totalErrorInfos.AddRange(expErrorInfos);
                    continue;
                }
                #endregion

                #region 查看M[U, a]表
                // 由于只有exp和标识符的情况会出现递归,所以其他非终结符号直接读取产生式即可
                List <ErrorInfo> NonErrorInfos = new List <ErrorInfo>();   // 在查找M[U,a]表时出现的错误
                if (symbolNode.IsLeaf)
                {
                    // 如果符号栈栈顶是终结符号
                    // 如果是结束符号
                    if (symbolNode.TSymbol == TerminalType.END)
                    {
                        if (token.TokenType == TerminalType.END)
                        {
                            // 语法分析结束,语法分析成功
                            symbolStack.Pop();
                            inputStack.Pop();
                            break;
                        }
                        else
                        {
                            // TODO 语法分析出错处理
                            ErrorEncapsulation("程序结尾存在多余字符串");
                            //isSuccess = false;
                        }
                    }

                    // 如果终结符号不是结束符号,则判断与输入表栈顶是否相同
                    if (symbolNode.TSymbol == token.TokenType)
                    {
                        // 将符号表和输入表栈顶元素出栈
                        // 如果符号栈栈顶元素是后一个元素子结点中的最后一个节点,则
                        // 应该将上一个结点也出栈
                        symbolNode.StringValue = token.StrValue;
                        symbolNode.LineNum     = token.LineNum;
                        PopSymbolStack();
                        inputStack.Pop();
                    }
                    else
                    {
                        // TODO 语法分析出错处理
                        ErrorEncapsulation($"缺少符号 '{T2String(symbolNode.TSymbol)}'");
                    }
                }
                else
                {
                    // 如果查找表失败则进行错误处理
                    if (!LookUpTable(symbolNode, out NonErrorInfos))
                    {
                        // TODO 出错处理
                        ErrorEncapsulation($"语法成分 '{N2String(symbolNode.NSymbol)}' 不能以" +
                                           $" '{T2String(token.TokenType)}' 符号开头");
                    }
                }
                #endregion
            }
            #endregion

            // 返回构建好的语法分析树
            //this.targetTree.IsSuccess = isSuccess;
            this.targetTree.ErrorInfos = this.targetTree.ErrorInfos.OrderBy(e => e.LineNum).ToList();

            return(this.targetTree);
        }
Example #5
0
 /// <summary>
 /// 调用语法分析程序
 /// </summary>
 /// <param name="tokenResult">词法分析结果</param>
 /// <param name="bpList">breakPoint列表,断点所在行数</param>
 /// <returns>语法分析树</returns>
 public ParseTree SyntacticAnalyse(TokenResult tokenResult, List <int> bpList)
 {
     return(this.syntacticAnalyser.SyntacticAnalysis(tokenResult,
                                                     bpList));
 }
Example #6
0
        public static List <RowTabel> run(string input)
        {
            int             line     = 1; //第几行
            int             n        = 1; //第几个
            int             count    = 0; //总的表下标
            List <RowTabel> rowTabel = new List <RowTabel>();
            //总的表
            TokenResult result = WordAnalyser.Analyse(input);

            //每一行字符串
            System.IO.StringReader sr = new System.IO.StringReader(input);
            string str = sr.ReadLine();
            //每一行的表
            TokenResult temp = WordAnalyser.Analyse(str);

            for (; ;)
            {
                //每一个单词逐步对应
                for (int i = 0; i < temp.Tokens.Count; i++)
                {
                    //如果相等,直接打印
                    if (temp.Tokens[i].StrValue == result.Tokens[count].StrValue)
                    {
                        rowTabel.Add(new RowTabel()
                        {
                            Name = result.Tokens[count].StrValue,
                            Id   = result.Tokens[count].TokenType,
                            Row  = line,
                            Num  = n
                        });
                        n++;
                        count++;
                    }
                    //如果不相等
                    //1、说明表中下一个单词是多行的
                    else if (result.Tokens[count].StrValue.IndexOf(temp.Tokens[i].StrValue) == 0)
                    {
                        //获取多行单词的行数
                        Console.WriteLine(result.Tokens[count].StrValue + "    " + line + "    " + n);
                        int t = huanHangCiShu(result.Tokens[count].StrValue);
                        while (t > 1)
                        {
                            str = sr.ReadLine();
                            line++;
                            t--;
                        }
                        count++;
                        break;
                    }
                    //2、上一个多行单词“残留”在本行
                    //①只有该残留的单词
                    else if (temp.Tokens.Count == 1)
                    {
                        break;
                    }
                    else
                    //②残留单词后方还有单词
                    {
                        n++;
                    }
                }
                //重新获取下一行的数据
                str = sr.ReadLine();
                if (str == null)
                {
                    break;
                }
                temp = WordAnalyser.Analyse(str);
                line++;
                n = 1;
                //直到读完才退出
                if (count == result.Tokens.Count)
                {
                    break;
                }
            }
            return(rowTabel);
        }