📄 ganalysis.cs
字号:
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;
using System.Windows.Forms;
namespace CmmInterpretor
{
class GrammerAnalysis
{
//语法分析,获得分析结果
public void AnalyzeCode(string sourceCode, ref string analysisText,
ref TreeView gmTree)
{
bool isRemark = false;
wordAnalysis.RemoveRemark(ref sourceCode, ref isRemark);
sourceCode = Regex.Replace(sourceCode, @"[\t\n\r]", " ").ToString();
//初步判断词法错误
wordAnalysis.ErrorNum = 0; //归0(set方法已重载)
string[] words = wordAnalysis.GetWords(sourceCode);
foreach (string word in words)
wordAnalysis.GetWordType(word); //该方法可计算错误单词数
int errWordNum = wordAnalysis.ErrorNum;
if (errWordNum > 0)
{
DialogResult response =
MessageBox.Show("代码中有" + Convert.ToString(errWordNum)
+ "个词法错误。是否要继续分析",
"确定", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
resultText += "代码中有"
+ Convert.ToString(errWordNum) + "个词法错误。"
+ "点击“词法分析”了解具体内容。\r\n\r\n";
if (response == System.Windows.Forms.DialogResult.No)
return;
}
//获得语法树
TreeForm treeForm = new TreeForm();
treeForm.Show();
trv = treeForm.getTree();
trv.Nodes.Clear();
trv.Nodes.Add("Source Code");
//进行语法分析
while (true)
{
CMMStatement curSt = SeparateFirstStatement(ref sourceCode);
if (curSt.Type == NULLST)
break;
else
{
TreeNode stNode = GetNode(curSt);
if (stNode != null)
trv.Nodes[0].Nodes.Add(stNode);
}
}
//更新语法树
trv.Update();
trv.ExpandAll();
analysisText = resultText;
gmTree = trv;
}
//由句首初步判断首语句类型
private int InitType(string sourceCode)
{
sourceCode = sourceCode.TrimStart();
//无语句
if (sourceCode.Length == 0)
return NULLST;
//空语句
if (sourceCode.StartsWith(";"))
{
return EMPTY;
}
//复合语句
if (sourceCode.StartsWith("{"))
{
return COMPLEX;
}
foreach (string rsvw in ReservedWords)
{
//若语句首是关键字,则可直接进行初步判断
if (sourceCode.StartsWith(rsvw) && sourceCode.Length > rsvw.Length)
{
string[] wordtmp = wordAnalysis.GetWords(
sourceCode.Substring(0, rsvw.Length + 1));//多取一位排除干扰
switch (wordtmp[0])
{
case "int": //声明语句类型
case "real":
return DECLARE;
case "read"://输入语句类型
return INPUT;
case "write"://输出语句类型
return OUTPUT;
case "while"://循环语句类型
return LOOP;
case "if"://选择语句类型
return SELECT;
case "else"://if语句的else分支
return ELSE_BR;
//可能是与关键字相同开头的标识符
default:
break;
}
}
}
//若句首没有关键字,则认为是赋值语句(如果是错误语句可在后续分析中判断出来)
return ASSIGN;
//是否为错误语句需要进一步判断
}
//分离sourceCode中的第一条语句
public CMMStatement SeparateFirstStatement(ref string sourceCode)
{
CMMStatement curSt = new CMMStatement();
sourceCode = sourceCode.TrimStart();
curSt.Type = InitType(sourceCode);
int firstSemi = sourceCode.IndexOf(";"); //第一个';'的位置
switch (curSt.Type)
{
case NULLST: //无语句,无法分离
curSt.Con = "";
break;
case EMPTY: //空语句
curSt.Con = ";";
sourceCode = sourceCode.Remove(0, 1);
break;
case COMPLEX:
string complexSt = "{";
if (GetBracketContent(ref sourceCode, ref complexSt))
{
complexSt += "}";
}
else
{
//若括号不匹配,则将代码全部剥离出来
complexSt += sourceCode;
sourceCode = "";
}
curSt.Con = complexSt;
break;
case DECLARE: //声明语句
case ASSIGN: //赋值语句
case INPUT: //输入语句
case OUTPUT: //输出语句
if (firstSemi < 0)
{
//将代码全部剥离出来
curSt.Con = sourceCode;
sourceCode = "";
curSt.Type = ERROR;
dealError(curSt.Con, " 缺少';'");
}
else
{
//语句至第一个';'
curSt.Con = sourceCode.Substring(0, firstSemi + 1);
sourceCode = sourceCode.Remove(0, firstSemi + 1);
}
break;
case LOOP:
case ELSE_BR:
if (firstSemi < 0)
{
//将代码全部剥离出来
curSt.Con = sourceCode;
sourceCode = "";
curSt.Type = ERROR;
dealError(curSt.Con, " 缺少';'");
break;
}
curSt.Con = sourceCode.Substring(0, firstSemi + 1);
//第一个';'前的语句如果不包括'{',则不必进一步判断
if (!curSt.Con.Contains("{"))
{
sourceCode = sourceCode.Remove(0, firstSemi + 1);
}
//否则读取以"{"开头的复合语句
else
{
curSt.Con = sourceCode.Substring(0, sourceCode.IndexOf("{"));
sourceCode = sourceCode.Remove(0, sourceCode.IndexOf("{"));
CMMStatement cmpSt = SeparateFirstStatement(ref sourceCode);
curSt.Con += cmpSt.Con;
}
break;
case SELECT:
if (firstSemi < 0)
{
//将代码全部剥离出来
curSt.Con = sourceCode;
sourceCode = "";
dealError(curSt.Con, " 缺少';'");
break;
}
curSt.Con = sourceCode.Substring(0, firstSemi + 1);
//第一个';'前的语句如果不包括'{',则不必进一步判断
if (!curSt.Con.Contains("{"))
{
sourceCode = sourceCode.Remove(0, firstSemi + 1);
}
//否则读取以"{"开头的复合语句
else
{
curSt.Con = sourceCode.Substring(0, sourceCode.IndexOf("{"));
sourceCode = sourceCode.Remove(0, sourceCode.IndexOf("{"));
CMMStatement thenSt = SeparateFirstStatement(ref sourceCode);
if (thenSt.Type != NULLST)
{
curSt.Con += thenSt.Con;
}
}
//判断是否含else分支
int elseStType = InitType(sourceCode);
if (elseStType == ELSE_BR)
{
CMMStatement elseSt = SeparateFirstStatement(ref sourceCode);
curSt.Con += elseSt.Con;
}
break;
default: //不会含其他情况,除非出现异常
dealError(curSt.Con, "运行出现异常");
break;
}
return curSt;
}
//分析语句元素,并修正语句类型
public void AnalyzeStatement(ref CMMStatement st)
{
st.Con = st.Con.Trim();
st.Type = InitType(st.Con);
switch (st.Type)
{
case NULLST: //无语句
case EMPTY: //空语句
case ERROR: //错误语句
break;
case COMPLEX: //复合语句
AnalyzeComplex(ref st);
break;
case DECLARE: //声明语句
AnalyzeDeclare(ref st);
break;
case INPUT: //输入语句
AnalyzeInput(ref st);
break;
case OUTPUT: //输出语句
AnalyzeOutput(ref st);
break;
case ASSIGN: //赋值语句
AnalyzeAssign(ref st);
break;
case LOOP: //循环语句
AnalyzeLoop(ref st);
break;
case SELECT: //选择语句
AnalyzeSelect(ref st);
break;
case ELSE_BR: //if语句的else分支
dealError(st.Con, "else语句应紧接if语句then分支后,不可单独使用");
break;
default:
break;
}
}
//分析复合语句
private void AnalyzeComplex(ref CMMStatement st)
{
string stCon = st.Con;
if (stCon.EndsWith("}"))
st.Els[0] = stCon.Substring(1, stCon.Length - 2);
else
{
st.Type = ERROR;
dealError(st.Con, "缺少'}'");
}
}
//分析声明语句
private void AnalyzeDeclare(ref CMMStatement st)
{
ArrayList stWords = wordAnalysis.GetWordLst(st.Con);
//声明语句:int|real 标识符;
if (stWords.Count == 3
&& wordAnalysis.GetWordType((string)stWords[1]) == ID)
{
st.Els[0] = (string)stWords[1];
st.Els[1] = (string)stWords[0];
st.Els[2] = NOTARR;
st.Els[3] = NOTASS;
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -