/// <summary> /// Обновляет данные для процедур позицию строк деклараций и блока begin/end из кода скрипта /// </summary> /// <param name="_pi">Данные которые требуется обновить</param> /// <param name="text">Текущий текст скрипта</param> /// <param name="scriptFile">Файл скрипта</param> public static void UpdateProcInfo(ref ProgramInfo _pi, string text, string scriptFile) { UpdateParseBuffer(text); List <string> procedureNames; List <ProcedureBlock> listBlock = GetAllProceduresBlock(out procedureNames); for (int i = 0; i < _pi.procs.Length; i++) { if (_pi.procs[i].fdeclared != scriptFile) { continue; } string pName = _pi.procs[i].Name; int n = procedureNames.FindIndex(name => name == pName); if (n == -1 || n >= listBlock.Count) { continue; } _pi.procs[i].d.declared = listBlock[n].declar + 1; _pi.procs[i].d.start = (listBlock[n].begin >= 0) ? listBlock[n].begin + 1 : -1; _pi.procs[i].d.end = (listBlock[n].end >= 0) ? listBlock[n].end + 1 : -1; _pi.procs[i].d.defined = _pi.procs[i].d.start; } _pi.RebuildProcedureDictionary(); bufferSSLCode = null; }
// Get new procedure data of script public static Procedure[] GetProcsData(string textscript, string filepath) { UpdateParseBuffer(textscript, false); // Не переводить в нижний регист для получения правильных имен процедур ProgramInfo _pi = InternalProcParse(new ProgramInfo(CountProcedures, 0), textscript, filepath); return(_pi.procs); }
/// <summary> /// Internal parse script /// </summary> /// <param name="_ti"></param> /// <param name="frm"></param> public ParserInternal(TabInfo _ti, Form frm) { scrptEditor = frm as TextEditor; TextEditor.parserIsRunning = true; // internal parse work UpdateParseBuffer(_ti.textEditor.Text, false); ProgramInfo _pi = new ProgramInfo(CountProcedures, 0); _ti.parseInfo = InternalProcParse(_pi, _ti.textEditor.Text, _ti.filepath); TextEditor.parserIsRunning = false; }
/// <summary> /// Обновляет данные о процедурах, удаляет устаревшие или добавляет новые /// </summary> /// <param name="_pi"></param> /// <param name="textscript"></param> /// <param name="filepath"></param> /// <returns></returns> public static ProgramInfo UpdateProcsPI(ProgramInfo _pi, string textscript, string filepath) { List <Procedure> _proc = _pi.procs.ToList(); UpdateParseBuffer(textscript, false); ProgramInfo update_pi = InternalProcParse(new ProgramInfo(CountProcedures, 0), textscript, filepath); for (int i = 0; i < _proc.Count; i++) { bool exist = false; foreach (Procedure p in update_pi.procs) { if (p.name.Equals(_proc[i].name, StringComparison.OrdinalIgnoreCase) && _proc[i].fdeclared == p.fdeclared) { _proc[i].d.start = p.d.start; _proc[i].d.end = p.d.end; _proc[i].d.declared = p.d.declared; _proc[i].d.defined = p.d.defined; exist = true; break; } } if (!exist && _proc[i].IsLocal(filepath)) { _proc.RemoveAt(i--); // remove unused local procedure } } for (int i = 0; i < update_pi.procs.Length; i++) { bool exist = false; for (int j = 0; j < _proc.Count; j++) { if (update_pi.procs[i].name.Equals(_proc[j].name, StringComparison.OrdinalIgnoreCase) && update_pi.procs[i].fdeclared == _proc[j].fdeclared) { exist = true; break; } } if (!exist) { _proc.Insert(i, update_pi.procs[i]); // Add new procedure } } _pi.procs = _proc.ToArray(); _pi.RebuildProcedureDictionary(); return(_pi); }
public static void ParseNodeCode(string text, List <DialogueParser> args, ProgramInfo pi, bool diagram = false, bool excludeComment = true, StringSplitOptions splitOption = StringSplitOptions.RemoveEmptyEntries) { DialogueParser.pi = pi; int _comm = 0, _count = 0; Regex regex = new Regex(@"\b" + OpcodeType.call.ToString() + @"\b", RegexOptions.IgnoreCase); string[] bodyNode = text.Split(new char[] { '\n' }, splitOption); for (int i = 0; i < bodyNode.Length; i++) { nLine = i; string str = bodyNode[i].TrimEnd(); if (excludeComment || !diagram) { string _str = str.TrimStart(); if (ParserInternal.CommentBlockParse(ref _str, ref _comm)) { continue; } } if (excludeComment || diagram) { _count = args.Count; } ReplySubParse(args, str, OpcodeType.Message); ReplySubParse(args, str, OpcodeType.Reply); OptionSubParse(args, str); MiscSubParse(args, str); // для макросов использующихся как переход к ноде // for call opcode MatchCollection matches = regex.Matches(str); foreach (Match m in matches) { args.Add(new DialogueParser(OpcodeType.call, null, str, m.Index + 4)); } // для диаграмм добавляем строку кода из ноды if (diagram && _count == args.Count) { args.Add(new DialogueParser(OpcodeType.None, null, str)); } } }
/// <summary> /// Получает новые данные о процедурах из кода скрипта /// </summary> /// <param name="_pi"></param> /// <param name="text">Текущий текст скрипта</param> /// <param name="scriptFile">Файл скрипта</param> /// <returns></returns> private static ProgramInfo InternalProcParse(ProgramInfo _pi, string text, string scriptFile, bool bufferUpdate = true) { #region Procedures info data /* pi.procs[].d.start - номер строки начала тела процедуры * pi.procs[].d.end - номер строки конца тела процедуры * pi.procs[].d.declared - номер строки с объявление процедуры * pi.procs[].name - имя процедуры * pi.procs[].fdeclared - путь и имя к файлу где объявлена процедура * pi.procs[].fstart - путь и имя к файлу где расположана процедура * pi.procs[].filename - имя файла скрипта */ #endregion if (bufferUpdate) { UpdateParseBuffer(text); } List <string> procedureNames; List <ProcedureBlock> listBlock = GetAllProceduresBlock(out procedureNames); for (int i = 0; i < procNameList.Count; i++) { _pi.procs[i] = new Procedure(); _pi.procs[i].name = procNameList[i]; int n = procedureNames.FindIndex(name => name == procNameList[i].ToLowerInvariant()); if (n == -1 || n >= listBlock.Count) { MessageBox.Show(String.Format("Error: The procedure '{0}' was not found in the checklist.", procNameList[i]), "Internal Parser"); continue; } _pi.procs[i].d.declared = listBlock[n].declar + 1; _pi.procs[i].d.start = (listBlock[n].begin >= 0) ? listBlock[n].begin + 1 : -1; _pi.procs[i].d.end = (listBlock[n].end >= 0) ? listBlock[n].end + 1 : -1; _pi.procs[i].d.defined = _pi.procs[i].d.start; _pi.procs[i].fdeclared = Path.GetFullPath(scriptFile); _pi.procs[i].fstart = _pi.procs[i].fdeclared; _pi.procs[i].filename = Path.GetFileName(scriptFile).ToLowerInvariant(); _pi.procs[i].references = new Reference[0]; // empty not used _pi.procs[i].variables = new Variable[0]; // empty not used } _pi.parsed = true; bufferSSLCode = null; return(_pi); }
public static ProgramInfo UpdatePI(ProgramInfo pi, string filepath) { string name = Path.GetFileName(filepath); for (int i = 0; i < pi.procs.Length; i++) { var p = pi.procs[i]; p.fdeclared = filepath; p.fstart = filepath; p.filename = name; for (int j = 0; j < p.references.Length; j++) { p.references[j].file = filepath; } for (int j = 0; j < p.variables.Length; j++) { p.variables[j].fdeclared = filepath; //p.variables[j].filename = name; for (int n = 0; n < p.variables[j].references.Length; n++) { p.variables[j].references[n].file = filepath; } } } for (int i = 0; i < pi.vars.Length; i++) { var v = pi.vars[i]; v.fdeclared = filepath; v.filename = name; for (int j = 0; j < v.references.Length; j++) { v.references[j].file = filepath; } } return(pi); }
public static void PrepareNodeCode(string nodeProcedureText, List <DialogueParser> args, ProgramInfo pi, bool excludeComment) { string[] preNodeBody = nodeProcedureText.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < preNodeBody.Length; i++) { preNodeBody[i] = preNodeBody[i].TrimEnd().Replace("\t", new string(' ', 3)); int n = 0; do { n = preNodeBody[i].IndexOf(";", n); if (n > 0) { if (++n >= preNodeBody[i].Length) { break; // выходим достигнут конец строки } int z = preNodeBody[i].IndexOf("else", n); if (excludeComment && z != -1) { z = (preNodeBody[i].IndexOf("//") != -1) ? -1 : z; //исключаем перенос для закоментированных строк кода } if (z < 0) { break; // в строке нет ключевого слова 'else' } int x; for (x = 0; x < preNodeBody[i].Length; x++) { if (!Char.IsWhiteSpace(preNodeBody[i][x])) { break; } } preNodeBody[i] = preNodeBody[i].Insert(z, Environment.NewLine + new string(' ', x)); n = z + 6; } } while (n > -1); } ParseNodeCode(String.Join("\n", preNodeBody), args, pi, true, excludeComment); }
public ProgramInfo Parse(string text, string filepath, ProgramInfo prev_pi) { // Parse disabled, get only macros if (Settings.enableParser && filepath != null) { File.WriteAllText(parserPath, text, Encoding.Default); try { lastStatus = parse_main(parserPath, filepath, Path.GetDirectoryName(filepath), Settings.preprocDef, (Settings.IsSearchIncludes) ? Settings.pathHeadersFiles : null, Settings.compileBackwardMode); } catch { lastStatus = 3; MessageBox.Show("An unexpected error occurred while parsing text of the script.\n" + "It is recommended that you save all unsaved documents and restart application,\n" + "in order to avoid further incorrect operation of the application.", "Error: Parser.dll"); }; } ProgramInfo pi = (lastStatus >= 1) ? prev_pi //new ProgramInfo(0, 0) : new ProgramInfo(numProcs(), numVars()); if (lastStatus >= 1 && prev_pi != null) // preprocess error - store previous data Procs/Vars { if (prev_pi.parsed) //.parseData { if (Settings.enableParser) { pi = (!pi.reParseData) ? ParserInternal.UpdateProcsPI(prev_pi, text, filepath) : ParserInternal.UpdatePI(prev_pi, filepath); } else if (firstParse) { pi.RebuildProcedureDictionary(); } } if (!pi.reParseData) { pi.macros.Clear(); } } pi.parseError = (lastStatus != 0 & Settings.enableParser); // // Macros // string[] scriptCode = text.Split('\n'); if (!pi.reParseData) { new GetMacros(scriptCode, filepath, Path.GetDirectoryName(filepath), pi.macros); } pi.parsed = true; pi.reParseData = false; if (lastStatus >= 1) { return(pi); // parse failed, return macros and previous parsed data Procs/Vars } // // Getting data of variables/procedures // pi.parseData = true; // received data from parser.dll byte[] names = new byte[namespaceSize()]; int stringsSize = stringspaceSize(); getNamespace(names); byte[] strings = null; if (stringsSize > 0) { strings = new byte[stringsSize]; getStringspace(strings); } // Variables for (int i = 0; i < pi.vars.Length; i++) { pi.vars[i] = new Variable(); getVar(i, out pi.vars[i].d); pi.vars[i].name = ParseName(names, pi.vars[i].d.name); if (pi.vars[i].d.initialized != 0) { switch (pi.vars[i].d.initialType) { case ValueType.Int: pi.vars[i].initialValue = pi.vars[i].d.intValue.ToString(); break; case ValueType.Float: pi.vars[i].initialValue = pi.vars[i].d.floatValue.ToString(); break; case ValueType.String: pi.vars[i].initialValue = '"' + ParseName(strings, pi.vars[i].d.intValue) + '"'; break; } } if (pi.vars[i].d.fdeclared != IntPtr.Zero) { pi.vars[i].fdeclared = Path.GetFullPath(Marshal.PtrToStringAnsi(pi.vars[i].d.fdeclared)); pi.vars[i].filename = Path.GetFileName(pi.vars[i].fdeclared).ToLowerInvariant(); } if (pi.vars[i].d.numRefs == 0) { pi.vars[i].references = new Reference[0]; } else { int[] tmp = new int[pi.vars[i].d.numRefs * 2]; getVarRefs(i, tmp); pi.vars[i].references = new Reference[pi.vars[i].d.numRefs]; for (int j = 0; j < pi.vars[i].d.numRefs; j++) { pi.vars[i].references[j] = Reference.FromPtr(tmp[j * 2], tmp[j * 2 + 1]); } } } // Procedures for (int i = 0; i < pi.procs.Length; i++) { pi.procs[i] = new Procedure(); getProc(i, out pi.procs[i].d); pi.procs[i].name = ParseName(names, pi.procs[i].d.name); if (pi.procs[i].d.fdeclared != IntPtr.Zero) { //pi.procs[i].fdeclared=Marshal.PtrToStringAnsi(pi.procs[i].d.fdeclared); pi.procs[i].fdeclared = Path.GetFullPath(Marshal.PtrToStringAnsi(pi.procs[i].d.fdeclared)); pi.procs[i].filename = Path.GetFileName(pi.procs[i].fdeclared).ToLowerInvariant(); } if (pi.procs[i].d.fstart != IntPtr.Zero) { //pi.procs[i].fstart = Marshal.PtrToStringAnsi(pi.procs[i].d.fstart); pi.procs[i].fstart = Path.GetFullPath(Marshal.PtrToStringAnsi(pi.procs[i].d.fstart)); } //pi.procs[i].fend=Marshal.PtrToStringAnsi(pi.procs[i].d.fend); if (pi.procs[i].d.numRefs == 0) { pi.procs[i].references = new Reference[0]; } else { int[] tmp = new int[pi.procs[i].d.numRefs * 2]; getProcRefs(i, tmp); pi.procs[i].references = new Reference[pi.procs[i].d.numRefs]; for (int j = 0; j < pi.procs[i].d.numRefs; j++) { pi.procs[i].references[j] = Reference.FromPtr(tmp[j * 2], tmp[j * 2 + 1]); } } // Procedure variables if (getProcNamespaceSize(i) == -1) { pi.procs[i].variables = new Variable[0]; } else { byte[] procnames = new byte[getProcNamespaceSize(i)]; getProcNamespace(i, procnames); pi.procs[i].variables = new Variable[pi.procs[i].d.numVariables]; for (int j = 0; j < pi.procs[i].variables.Length; j++) { Variable var = pi.procs[i].variables[j] = new Variable(); getProcVar(i, j, out var.d); var.name = ParseName(procnames, var.d.name); if (var.d.initialized != 0) { switch (var.d.initialType) { case ValueType.Int: var.initialValue = var.d.intValue.ToString(); break; case ValueType.Float: var.initialValue = var.d.floatValue.ToString(); break; case ValueType.String: var.initialValue = '"' + ParseName(strings, var.d.intValue) + '"'; break; } } var.fdeclared = Marshal.PtrToStringAnsi(var.d.fdeclared); if (var.d.numRefs == 0) { var.references = new Reference[0]; } else { int[] tmp = new int[var.d.numRefs * 2]; getProcVarRefs(i, j, tmp); var.references = new Reference[var.d.numRefs]; for (int k = 0; k < var.d.numRefs; k++) { var.references[k] = Reference.FromPtr(tmp[k * 2], tmp[k * 2 + 1]); } } var.adeclared = ParseProcedureArguments(pi.procs[i].d.start, var.d.declared, var.name.ToLowerInvariant(), scriptCode); } } } pi.BuildDictionaries(); return(pi); }