📄 phraseanalyzer.cs
字号:
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Globalization;
namespace PhraseAnalyzer
{
/// <summary>
/// 词法分析类
/// </summary>
public class PhraseAnalyzer
{
private DFAState _prestate; //DFA的前一个状态
private char[] _chArray=null; //句子变量的字符串形式
private string _sentence=null; //句子变量
private PhraseStorage _ps=null;
public PhraseAnalyzer(string sentence,ref PhraseStorage ps)
{
//清除前一次的词法分析结果
_ps=ps;
_ps.ClearResult();
//保存句子
_sentence=sentence;
//小写化句子中的所有字母
_chArray=sentence.ToLower().ToCharArray();
if(Analyze()==false) //出错
_ps.AddPhraseResult("出错",PhraseType.unknown);
}
/// <summary>
/// 保存词
/// </summary>
/// <param name="startpos">开始位置</param>
/// <param name="endpos">结束位置</param>
private void SavePhrase(int startpos,int endpos)
{
string temp=null;
if(endpos>=0 && startpos>=0 && endpos>=startpos)
{
temp=_sentence.Substring(startpos,endpos-startpos+1);
_ps.AddPhraseResult(temp,PhraseAnalyzer.StrToType(temp));
}
}
/// <summary>
/// 转换字符串为所对应的词类
/// </summary>
/// <param name="str">词字符串</param>
/// <returns></returns>
public static PhraseType StrToType(string str)
{
switch(str)
{
case "sin": return PhraseType.sin;
case "cos": return PhraseType.cos;
case "ln": return PhraseType.ln;
case "lg": return PhraseType.lg;
case "log": return PhraseType.log;
case "^": return PhraseType.pow;
case "cbrt": return PhraseType.cbrt;
case "sbrt": return PhraseType.sbrt;
case "asin": return PhraseType.asin;
case "acos": return PhraseType.acos;
case "!": return PhraseType.fact;
case "tg": return PhraseType.tg;
case "ctg": return PhraseType.ctg;
case "atg":return PhraseType.atg;
case "actg":return PhraseType.actg;
case "+":return PhraseType.plus;
case "-":return PhraseType.minus;
case "*":return PhraseType.mutiple;
case "/":return PhraseType.divide;
case "%":return PhraseType.mod;
case "(":return PhraseType.leftbracket;
case ")":return PhraseType.rightbracket;
case "ans":return PhraseType.ans;
case "sto":return PhraseType.sto;
case "clr":return PhraseType.clr;
case "A": return PhraseType.ax;
case "B": return PhraseType.bx;
case "C": return PhraseType.cx;
case "D": return PhraseType.dx;
case "E": return PhraseType.ex;
case "F": return PhraseType.fx;
case "e": return PhraseType.e;
case "PI": return PhraseType.pi;
default: return PhraseType.number;
}
}
/// <summary>
/// 词法分析
/// </summary>
/// <returns>是否成功</returns>
private bool Analyze()
{
int i=0;
int startpos=0,endpos=0;
//设置初态
_prestate=DFAState.S0;
while(i<_chArray.Length){
//未知态处理,出错返回
if(_prestate==DFAState.SX)
return false;
if(Char.IsLetter(_chArray[i]))
{
//字母
if(_prestate==DFAState.S0)
{
//初态变字母串
_prestate=DFAState.S3;
}
else if(_prestate!=DFAState.S3)
{
//处理前一个词
endpos=i-1; //保存结束位置
SavePhrase(startpos,endpos);
//非字母串转换为字母串
_prestate=DFAState.S3;
//保存开始位置
startpos=i;
}
}
else if(Char.IsDigit(_chArray[i]))
{
//数字
if(_prestate==DFAState.S0)
{
//初态
_prestate=DFAState.S1;
startpos=i; //保存开始位置
}
else if(_prestate==DFAState.S1)
{
//整数串,状态不变
}
else if(_prestate==DFAState.S2) //浮点数串
_prestate=DFAState.S2;
else
{
//处理前一个词
endpos=i-1; //保存结束位置
SavePhrase(startpos,endpos);
//从非数字串转换为整数串
_prestate=DFAState.S1;
//保存开始位置
startpos=i;
}
}
else if(_chArray[i]=='.')
{
//小数点
if(_prestate==DFAState.S1||_prestate==DFAState.S0)
_prestate=DFAState.S2; //由整数串或初态变为浮点数串
else
{ //未知态
// 需要讨论: 是否保存前一个词
_prestate=DFAState.SX;
}
}
else if(Char.IsWhiteSpace(_chArray[i]))
{
//空格,跳过
}
/* 重复,暂时删除
else if(Char.GetUnicodeCategory(_chArray[i])==UnicodeCategory.ClosePunctuation)
{
if(_prestate!=DFAState.S0)
{
//处理前一个词
endpos=i-1;
SavePhrase(startpos,endpos);
}
if(_chArray[i]=='(') //左括号
_prestate=DFAState.S12;
else if(_chArray[i]==')') //右括号
_prestate=DFAState.S13;
//保存开始位置
startpos=i;
}*/
else if(_chArray[i]=='@')
{
//负数标志
if(_prestate==DFAState.S0) //初态
{
_prestate=DFAState.S1; //整数串
}else if(_prestate==DFAState.S1||_prestate==DFAState.S2) //整数串或浮点数串
_prestate=DFAState.SX; //未知态
else{
//处理前一个词
endpos=i-1;
SavePhrase(startpos,endpos);
//整数串
_prestate=DFAState.S1;
//保存开始位置
startpos=i;
}
}
else if(_chArray[i]=='+'||_chArray[i]=='-'||_chArray[i]=='*'||_chArray[i]=='/'||_chArray[i]=='^'||_chArray[i]=='%'||_chArray[i]=='='||_chArray[i]=='('||_chArray[i]==')'||_chArray[i]=='!')
{
if(_prestate!=DFAState.S0)
{
//处理前一个词
endpos=i-1;
SavePhrase(startpos,endpos);
}
if(_chArray[i]=='+')
_prestate=DFAState.S4;
else if(_chArray[i]=='-')
_prestate=DFAState.S5;
else if(_chArray[i]=='*')
_prestate=DFAState.S6;
else if(_chArray[i]=='/')
_prestate=DFAState.S7;
else if(_chArray[i]=='=')
_prestate=DFAState.S11;
else if(_chArray[i]=='%')
_prestate=DFAState.S8;
else if(_chArray[i]=='^')
_prestate=DFAState.S10;
else if(_chArray[i]=='(')
_prestate=DFAState.S12;
else if(_chArray[i]==')')
_prestate=DFAState.S13;
else if(_chArray[i]=='!')
_prestate=DFAState.S9;
//保存开始位置
startpos=i;
}
else
{
// 需要讨论: 是否保存前一个词
//未知字符,进入未知态
_prestate=DFAState.SX;
}
i++;
}
return true;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -