/// <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); }
/// <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); }
/// <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)); }
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); }