Beispiel #1
0
        /// <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;
        }
Beispiel #2
0
        // 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);
        }
Beispiel #3
0
        /// <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;
        }
Beispiel #4
0
        /// <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));
                }
            }
        }
Beispiel #6
0
        /// <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);
        }
Beispiel #7
0
        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);
        }