123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456 |
- using GDNXFD.Data;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Threading.Tasks;
- namespace GDNXFD.Alert.Interpreter
- {
- public class CodeGenerator
- {
- private string className;
- private string expression;
- private List<string> varList;
- private Stack<SustainModel> sustainStack;
- private List<SustainModel> sustainList;
- private Stack<char> barcketStack;
- private int sustainSeq = 1;
- public CodeGenerator(string clsName, string exps)
- {
- if (string.IsNullOrWhiteSpace(clsName))
- {
- className = GenerateRandomString(10);
- }
- else
- {
- className = clsName.Trim();
- }
- varList = new List<string>();
- if (string.IsNullOrWhiteSpace(exps))
- {
- varList.Add("true");
- return;
- }
- try
- {
- expression = exps.Trim().TrimEnd(';');
- expression = ReplaceStatusContinued(expression);
- expression = ReplaceSuddenChange(expression);
- expression = ReplaceLastUpdateTime(expression);
- expression = ReplaceDiffMinutes(expression);
- expression = ReplaceDiffSeconds(expression);
- PhrasingExpression(expression);
- if (varList != null && varList.Count > 0)
- {
- foreach (string strVar in varList)
- {
- if (DataCache.Instance.RelateUniformCodes == null)
- DataCache.Instance.RelateUniformCodes = new List<string>();
- if (!DataCache.Instance.RelateUniformCodes.Contains(strVar))
- DataCache.Instance.RelateUniformCodes.Add(strVar);
- }
- }
- if (sustainList != null && sustainList.Count > 0)
- {
- foreach (SustainModel sm in sustainList)
- {
- if (string.IsNullOrEmpty(sm.Expression) || sm.EndIndex == 0 || sm.Duration==0)
- throw new ExpressionException("Sustain方法不完整!");
- if (sm.VarList != null)
- {
- foreach (string strVar in sm.VarList)
- {
- if (DataCache.Instance.RelateUniformCodes == null)
- DataCache.Instance.RelateUniformCodes = new List<string>();
- if (!DataCache.Instance.RelateUniformCodes.Contains(strVar))
- DataCache.Instance.RelateUniformCodes.Add(strVar);
- }
- }
- }
- }
- }
- catch(ExpressionException)
- {
- throw;
- }
- catch (Exception ex)
- {
- throw new ExpressionException(ex);
- }
- }
- public void PhrasingExpression(string exps)
- {
- char[] arr = exps.ToCharArray();
- for (int i = 0; i < arr.Length; i++)
- {
- #region Sustain函数开始匹配
- if (arr[i] == 'S' && i + 7 < arr.Length &&
- arr[i + 1] == 'u' &&
- arr[i + 2] == 's' &&
- arr[i + 3] == 't' &&
- arr[i + 4] == 'a' &&
- arr[i + 5] == 'i' &&
- arr[i + 6] == 'n')
- {
- int offset = i;
- i += 7;
- while (IsWhite(arr[i]) && i < arr.Length - 1) i++; //去除空白
- if (arr[i] == '(')
- {
- SustainModel sModel = new SustainModel();
- sModel.Sequence = sustainSeq++;
- sModel.StartIndex = offset;
- if (sustainStack == null)
- sustainStack = new Stack<SustainModel>();
- if (sustainStack.Count > 0)
- {
- SustainModel sm = sustainStack.Peek();
- if (sm.SustainList == null)
- sm.SustainList = new List<SustainModel>();
- sm.SustainList.Add(sModel);
- }
- sustainStack.Push(sModel);
- if (sustainStack.Count == 1)
- {
- if (sustainList == null)
- sustainList = new List<SustainModel>();
- sustainList.Add(sModel);
- }
- i++;
- }
- }
- #endregion
- #region AI、DI变量匹配
- //AI, DI变量提取
- if ((arr[i] == 'A' || arr[i] == 'D') && i + 1 < arr.Length && arr[i + 1] == 'I')
- {
- if (i == 0 || !IsLetterOrNumber(arr[i-1]))
- {
- int offset = i;
- i += 2;
- while ((IsLetterOrNumber(arr[i]) || arr[i] == '_') && i < arr.Length - 1) i++; //提取以AI或DI开头的单词
- string expVar = new string(arr, offset, i == arr.Length - 1 ? i - offset + 1 : i - offset);
- if (sustainStack != null && sustainStack.Count > 0)
- {
- SustainModel sm = sustainStack.Peek();
- if (sm.VarList == null)
- sm.VarList = new List<string>();
- if (!sm.VarList.Contains(expVar))
- sm.VarList.Add(expVar);
- }
- else
- {
- if (varList == null)
- varList = new List<string>();
- if (!varList.Contains(expVar))
- varList.Add(expVar);
- }
- }
- }
- #endregion
- #region Sustain函数结尾匹配
- if (sustainStack != null && sustainStack.Count > 0)
- {
- SustainModel sm = sustainStack.Peek();
- if (arr[i] == '(')
- {
- if (barcketStack == null)
- barcketStack = new Stack<char>();
- barcketStack.Push('(');
- }
- else if (arr[i] == ')')
- {
- if (barcketStack != null && barcketStack.Count > 0)
- {
- barcketStack.Pop();
- }
- else
- {
- sm.EndIndex = i;
- sm.Expression = new string(arr, sm.StartIndex, sm.EndIndex-sm.StartIndex+1);
- if (sm.Duration == 0 && sm.DurationIndex !=0)
- {
- string strDuration = new string(arr, sm.DurationIndex, sm.EndIndex-sm.DurationIndex);
- int duration = 0;
- if (int.TryParse(strDuration.Trim(), out duration))
- {
- sm.Duration = duration;
- }
- else
- {
- throw new ExpressionException("表达式格式错误!位置:" + i);
- }
- }
- if (sm.Interval == 0 && sm.IntervalIndex != 0)
- {
- string str = new string(arr, sm.IntervalIndex, sm.EndIndex-sm.IntervalIndex);
- int interval = 0;
- if (int.TryParse(str.Trim(), out interval))
- {
- sm.Interval = interval;
- }
- else
- {
- throw new ExpressionException("表达式格式错误!位置:" + i);
- }
- }
- sustainStack.Pop();
- }
- }
- else if (arr[i] == ',')
- {
- if (barcketStack == null || barcketStack.Count == 0)
- {
- if (sm.DurationIndex == 0)
- sm.DurationIndex = i+1;
- else
- {
- sm.IntervalIndex = i+1;
- string strDuration = new string(arr, sm.DurationIndex, i-sm.DurationIndex);
- int duration = 0;
- if (int.TryParse(strDuration.Trim(), out duration))
- {
- sm.Duration = duration;
- }
- else
- {
- throw new ExpressionException("表达式格式错误!位置:" + i);
- }
- }
- }
- }
- }
- #endregion
- }
- }
- private bool IsLetterOrNumber(char c)
- {
- if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9'))
- return true;
- return false;
- }
- private bool IsWhite(char c)
- {
- if (c == ' ' || c == '\n' || c == '\r' || c == '\t')
- return true;
- return false;
- }
- public string ToClassString()
- {
- StringBuilder sbMembers = null;
- if (varList != null && varList.Count > 0)
- {
- sbMembers = new StringBuilder();
- foreach (string member in varList)
- {
- if (member.StartsWith("AI"))
- sbMembers.AppendLine(string.Format(CodeTemplate.AIDeclare, member));
- else if (member.StartsWith("DI"))
- sbMembers.AppendLine(string.Format(CodeTemplate.DIDeclare, member));
- }
- }
- string exps = expression;
- StringBuilder sbSustainMethod = null;
- if (sustainList != null && sustainList.Count > 0)
- {
- sbSustainMethod = new StringBuilder();
- foreach (SustainModel sm in sustainList)
- {
- exps = exps.Replace(sm.Expression, sm.GetCallString());
- GenerateSustainMethod(sm, ref sbSustainMethod);
- }
- }
- string retStatement = string.Format(CodeTemplate.ReturnStatement, exps);
- return string.Format(CodeTemplate.Outline, className,
- sbMembers == null ? "" : sbMembers.ToString(),
- retStatement,
- sbSustainMethod == null ? "" : sbSustainMethod.ToString());
- }
- public void GenerateSustainMethod(SustainModel sm, ref StringBuilder sbSustainMethod)
- {
- sbSustainMethod.Append(sm.ToMethodString());
- if (sm.SustainList != null)
- {
- foreach (SustainModel ssm in sm.SustainList)
- GenerateSustainMethod(ssm, ref sbSustainMethod);
- }
- }
- private string GenerateRandomString(int codeCount)
- {
- string str = string.Empty;
- int seed = new Random().Next();
- Random random = new Random(seed);
- for (int i = 0; i < codeCount; i++)
- {
- int num = random.Next();
- str = str + ((char)(65 + ((ushort)(num % 26)))).ToString();
- }
- return str;
- }
- private string ReplaceDiffMinutes(string exp)
- {
- if (!exp.Contains("DiffMinutes"))
- return exp;
- string regex = @"DiffMinutes\(\w+,\s*\d+\)";
- MatchCollection coll = Regex.Matches(exp, regex);
- foreach (Match item in coll)
- {
- string rplStr = ConvertDiffMinutes(item.Value);
- exp = exp.Replace(item.Value, rplStr);
- }
- return exp;
- }
- private string ConvertDiffMinutes(string sc)
- {
- string template = "DiffMinutes(\"STR{0}\",{1},objectId,objectType)";
- string tmp = sc.Trim();
- tmp = tmp.TrimStart('D', 'i', 'f', 'f', 'M', 'i', 'n', 'u', 't', 'e', 's');
- tmp = tmp.Trim();
- tmp = tmp.TrimStart('(');
- tmp = tmp.TrimEnd(')');
- string[] arr = tmp.Split(',');
- return string.Format(template, arr[0].Trim(), arr[1].Trim());
- }
- private string ReplaceDiffSeconds(string exp)
- {
- if (!exp.Contains("DiffSeconds"))
- return exp;
- string regex = @"DiffSeconds\(\w+,\s*\d+\)";
- MatchCollection coll = Regex.Matches(exp, regex);
- foreach (Match item in coll)
- {
- string rplStr = ConvertDiffSeconds(item.Value);
- exp = exp.Replace(item.Value, rplStr);
- }
- return exp;
- }
- private string ConvertDiffSeconds(string sc)
- {
- string template = "DiffSeconds(\"STR{0}\",{1},objectId,objectType)";
- string tmp = sc.Trim();
- tmp = tmp.TrimStart('D', 'i', 'f', 'f', 'S', 'e', 'c', 'o', 'n', 'd', 's');
- tmp = tmp.Trim();
- tmp = tmp.TrimStart('(');
- tmp = tmp.TrimEnd(')');
- string[] arr = tmp.Split(',');
- return string.Format(template, arr[0].Trim(), arr[1].Trim());
- }
- private string ReplaceStatusContinued(string exp)
- {
- if (!exp.Contains("StatusContinued"))
- return exp;
- string regex = @"StatusContinued\(\w+,\s*\d+\)";
- MatchCollection coll = Regex.Matches(exp, regex);
- foreach (Match item in coll)
- {
- string rplStr = ConvertStatusContinued(item.Value);
- exp = exp.Replace(item.Value, rplStr);
- }
- return exp;
- }
- private string ConvertStatusContinued(string sc)
- {
- string template = "StatusContinued(\"STR{0}\",{1},objectId,objectType)";
- string tmp = sc.Trim();
- tmp = tmp.TrimStart('S', 't', 'a', 't', 'u', 's', 'C', 'o', 'n', 't', 'i', 'n', 'u', 'e', 'd');
- tmp = tmp.Trim();
- tmp = tmp.TrimStart('(');
- tmp = tmp.TrimEnd(')');
- string[] arr = tmp.Split(',');
- return string.Format(template, arr[0].Trim(), arr[1].Trim());
- }
- private string ReplaceSuddenChange(string exp)
- {
- if (!exp.Contains("SuddenChange"))
- return exp;
- string regex = @"SuddenChange\(\w+,\s*\d+,\s*\d+(\.\d+)?\)";
- MatchCollection coll = Regex.Matches(exp, regex);
- foreach (Match item in coll)
- {
- string rplStr = ConvertSuddenChange(item.Value);
- exp = exp.Replace(item.Value, rplStr);
- }
- return exp;
- }
- private string ConvertSuddenChange(string sc)
- {
- string template = "SuddenChange(\"STR{0}\",{1},{2},objectId,objectType)";
- string tmp = sc.Trim();
- tmp = tmp.TrimStart('S', 'u', 'd', 'd', 'e', 'n', 'C', 'h', 'a', 'n', 'g','e');
- tmp = tmp.Trim();
- tmp = tmp.TrimStart('(');
- tmp = tmp.TrimEnd(')');
- string[] arr = tmp.Split(',');
- return string.Format(template, arr[0].Trim(), arr[1].Trim(), arr[2].Trim());
- }
- private string ReplaceLastUpdateTime(string exp)
- {
- if (!exp.Contains("LastUpdateTime"))
- return exp;
- string regex = @"LastUpdateTime\(\w+\)";
- MatchCollection coll = Regex.Matches(exp, regex);
- foreach (Match item in coll)
- {
- string rplStr = ConvertLastUpdateTime(item.Value);
- exp = exp.Replace(item.Value, rplStr);
- }
- return exp;
- }
- private string ConvertLastUpdateTime(string sc)
- {
- string template = "LastUpdateTime(\"STR{0}\",objectId,objectType)";
- string tmp = sc.Trim();
- tmp = tmp.TrimStart('L', 'a', 's', 't', 'U', 'p', 'd', 'a', 't', 'e', 'T', 'i', 'm', 'e');
- tmp = tmp.Trim();
- tmp = tmp.TrimStart('(');
- tmp = tmp.TrimEnd(')');
- return string.Format(template, tmp.Trim());
- }
- }
- }
|