using System.Collections.Generic; using System.Collections.Specialized; using System.IO; using System.Text.RegularExpressions; using System.Windows.Forms; namespace YLPublishTool { class Parser { int _nextPos; int _lineNum; int _lineStartPos; int _lineEndPos; string _source; StringReader _sr; bool _isGlobal; TreeNode _actionNode; List _treeNodes; NameValueCollection _globalProperties; NameValueCollection _actionProperties; public IEnumerable InnerParse(string source, NameValueCollection predefines = null) { _sr = new StringReader(_source = source); _nextPos = 0; _lineNum = 1; _lineStartPos = 0; _lineEndPos = 0; _isGlobal = false; _actionNode = null; _treeNodes = new List(); _globalProperties = predefines ?? new NameValueCollection(); _actionProperties = new NameValueCollection(); while (ReadLine(out string line)) { ParseLine(line.TrimStart()); } return _treeNodes; } private bool ReadLine(out string line) { line = null; _lineNum++; _lineStartPos = _nextPos; while (_sr.Peek() > 0) { _lineEndPos = _nextPos++; var ch = _sr.Read(); var lineBreak = ch == '\r'; if (lineBreak) { if (_sr.Peek() == '\n') { _nextPos++; _sr.Read(); } } else { lineBreak = ch == '\n'; } if (lineBreak) { break; } } if (_lineEndPos >= _lineStartPos) { line = _source.Substring(_lineStartPos, _lineEndPos - _lineStartPos).TrimEnd(); return true; } return false; } private void ParseLine(string line) { if (string.IsNullOrEmpty(line) || line[0] == '#') { return; } var tag = new ParseInfo { LineNum = _lineNum, OriginalText = line, ConvertedText = line, StartPos = _lineStartPos, EndPos = _lineEndPos }; if (line[0] == '[') { _actionNode = new TreeNode(line) { Tag = tag }; _treeNodes.Add(_actionNode); line = line.Trim(new[] { '[', ']' }); _isGlobal = line == "全局变量"; if (!_isGlobal && !Helper.ExistsAction(line)) { _actionNode.ForeColor = System.Drawing.Color.Red; tag.ErrorInfo = "没有找到对应的指令处理器"; } return; } if (_actionNode == null) { tag.ErrorInfo = "此处发生错误,脚本不会继续执行"; _actionNode = new TreeNode("缺失[]指令") { Tag = tag, ForeColor = System.Drawing.Color.Red }; _treeNodes.Add(_actionNode); } var tn = new TreeNode { Tag = tag }; _actionNode.Nodes.Add(tn); var index = line.IndexOf('='); if (index < 0) { tn.Text = "无效行,忽略"; tn.ForeColor = System.Drawing.Color.Red; return; } var left = line.Substring(0, index).TrimEnd(); if (left.Length < 1) { tn.Text = "无效行,忽略"; tn.ForeColor = System.Drawing.Color.Red; return; } index++; var right = line.Substring(index).TrimStart(); if (right.StartsWith("#")) { tn.Text = "注释说明,忽略"; tn.ForeColor = System.Drawing.Color.Red; return; } if (right.StartsWith("'''")) { var startPos = _lineStartPos + index; while (ReadLine(out string line2)) { if (line2.EndsWith("'''")) { break; } } right = _source.Substring(startPos, _lineEndPos - startPos).Trim().Trim('\''); } tag.OriginalText = right; right = ConvertTemplateString(right); if (right.Length > 0) { (_isGlobal ? _globalProperties : _actionProperties)[left] = right; } tn.Text = left + " ="; tag.ConvertedText = right; tag.EndPos = _lineEndPos; } private string ConvertTemplateString(string str) { if (string.IsNullOrEmpty(str) || str.IndexOf("${") < 0) { return str; } return Regex.Replace(str, @"\$\{(.+?)\}", m => { var name = m.Groups[1].Value; return _actionProperties[name] ?? _globalProperties[name]; }); } } class ParseInfo { public int LineNum; public int StartPos; public int EndPos; public string OriginalText; public string ConvertedText; public string ErrorInfo; } }