private int ParseProcedureArguments(int start, int end, string vName, string[] code)
        {
            if (start > code.Length)
            {
                return(-1);
            }

            int len = ParserInternal.VARIABLE.Length + vName.Length;

            for (int i = start - 1; i > end; i--)
            {
                string line = code[i].TrimStart().ToLowerInvariant();
                if (len > line.Length)
                {
                    continue;
                }

                int y = line.IndexOf(ParserInternal.VARIABLE);
                if (y == -1)
                {
                    continue;
                }
                line = ParserInternal.RemoveDoubleWhiteSpaces(line, y, 0);

TryPass:
                int x = line.IndexOf(ParserInternal.VARIABLE + vName, y);
                if (x > -1)
                {
                    char c = line[x + len];
                    if (c == '_' || Char.IsLetterOrDigit(c))
                    {
                        line = line.Remove(x, len);
                        goto TryPass;
                    }

                    int z = line.IndexOf(ParserInternal.BEGIN);
                    if (z > -1 && x > z)
                    {
                        break; // переменная находится за пределами begin
                    }
                    return(i + 1);
                }
                if (line.StartsWith(ParserInternal.PROCEDURE))
                {
                    break;  // найдена процедура, прерываем цикл
                }
            }
            return(-1);
        }
        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));
                }
            }
        }
Example #3
0
        public List <FoldMarker> GenerateFoldMarkers(IDocument document, string fileName, object parseInformation)
        {
            Procedure[] procs = (Procedure[])parseInformation;

            List <FoldMarker> list = new List <FoldMarker>(procs.Length);
            int minStart           = -1;

            fileName = fileName.ToLowerInvariant();
            for (int i = 0; i < procs.Length; i++)
            {
                string fstart = Path.GetFileName(procs[i].fstart ?? string.Empty).ToLowerInvariant();
                if (fstart != fileName || procs[i].d.start >= procs[i].d.end)
                {
                    continue;
                }
                int dstart = procs[i].d.start - 1;
                if (minStart > dstart || minStart == -1)
                {
                    minStart = dstart;
                }
                int len = document.GetLineSegment(procs[i].d.end - 1).Length;
                list.Add(new FoldMarker(document, dstart, 0, procs[i].d.end - 1, len, FoldType.MemberBody, " " + procs[i].name.ToUpperInvariant() + " "));
            }

            if (list.Count > 0 && Path.GetExtension(fileName) == ".ssl")
            {
                ProcedureBlock dRegion = ParserInternal.GetRegionDeclaration(document.TextContent, minStart);
                if (dRegion.end < 0)
                {
                    dRegion.end = minStart - 2;
                }
                if (dRegion.end > dRegion.begin)
                {
                    list.Add(new FoldMarker(document, dRegion.begin, 0, dRegion.end, 1000, FoldType.Region, " - Declaration Region - "));
                }
            }
            // Get variable and #if foldings block
            List <ProcedureBlock> blockList = ParserInternal.GetFoldingBlock(document.TextContent);

            foreach (ProcedureBlock block in blockList)
            {
                string str = block.copy ? TextUtilities.GetLineAsString(document, block.begin) + " "
                                        : " - Variables - ";
                list.Add(new FoldMarker(document, block.begin, 0, block.end, 1000, FoldType.TypeBody, str));
            }
            return(list);
        }
Example #4
0
        public GetMacros(string[] lines, string file, string dir, SortedDictionary <string, Macro> macros, bool include = true)
        {
            if (dir == null)
            {
                dir = Path.GetDirectoryName(file);
            }

            bool commentBlock = false;

            for (int i = 0; i < lines.Length; i++)
            {
                if (lines[i].Length < 2)
                {
                    continue;
                }
                lines[i] = lines[i].Replace('\t', ' ').Trim(); // убираем все лишнее

                #region Пропускаем закоментированные макросы

                if (lines[i].StartsWith("//"))
                {
                    continue;
                }
                if (!commentBlock)
                {
                    if (lines[i].StartsWith("/*"))
                    {
                        if (lines[i].LastIndexOf("*/") == -1)
                        {
                            commentBlock = true;                                   // в встроке нет закрывающего тэга
                        }
                        continue;
                    }
                }
                else
                {
                    int close = lines[i].IndexOf("*/");
                    if (close == -1)
                    {
                        continue;
                    }
                    commentBlock = false;
                    close       += 2;
                    if (close == lines[i].Length)
                    {
                        continue;
                    }
                    lines[i] = lines[i].Remove(0, close).TrimStart();
                }
                if (lines[i].Length <= 8)
                {
                    continue;                       // минимальное необходимое значение для ключевого слова #define
                }
                #endregion

                if (include && lines[i].StartsWith(ParserInternal.INCLUDE))
                {
                    string[] text = lines[i].Split('"');
                    if (text.Length < 2)
                    {
                        continue;
                    }
                    if (text[1].IndexOfAny(Path.GetInvalidPathChars()) != -1)
                    {
                        continue;
                    }
                    ParserInternal.GetIncludePath(ref text[1], dir);
                    new GetMacros(text[1], null, macros);
                }
                else if (lines[i].StartsWith(ParserInternal.DEFINE))
                {
                    // описание к макросу
                    List <string> desc      = new List <string>();
                    int           descBlock = 0;
                    for (int j = i - 1; j >= 0; j--)
                    {
                        if (descBlock <= 0 && lines[j].Length == 0)
                        {
                            break;
                        }

                        string line = lines[j];
                        int    n    = line.LastIndexOf(" **/");
                        if (descBlock == 0 && n == -1)
                        {
                            break;
                        }

                        if (n != -1)
                        {
                            descBlock++;
                            line = line.Remove(n);
                        }

                        n = line.IndexOf("/** ");
                        if (n != -1)
                        {
                            descBlock--;
                            if (descBlock < 0)
                            {
                                break;
                            }
                            line = line.Substring(n + 4);
                        }
                        desc.Add(line.Trim());
                    }
                    string description = null;
                    if (desc.Count > 0)
                    {
                        var sbDesc = new StringBuilder();
                        desc.Reverse();
                        foreach (var item in desc)
                        {
                            sbDesc.AppendLine(item);
                        }
                        description = sbDesc.ToString();
                    }

                    if (lines[i].EndsWith(@"\"))
                    {
                        var sb     = new StringBuilder();
                        int lineno = i;
                        lines[i] = lines[i].Substring(8);
                        do
                        {
                            sb.Append(lines[i].Remove(lines[i].Length - 1).TrimEnd()); // удаляем пробелы и символ '\' в конце макроса
                            sb.Append(Environment.NewLine);
                            i++;
                            lines[i] = lines[i].TrimEnd();
                        } while (lines[i].EndsWith(@"\"));
                        sb.Append(lines[i]);
                        AddMacro(sb.ToString(), macros, file, lineno, description);
                    }
                    else
                    {
                        AddMacro(lines[i].Substring(8), macros, file, i, description);
                    }
                }
            }
        }
        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);
        }
Example #6
0
 /// <summary>
 /// Get information about the location of procedures for updating Foldings
 /// </summary>
 internal static void UpdateFolding(IDocument document, string filepath)
 {
     Procedure[] parseInformation = ParserInternal.GetProcsData(document.TextContent, filepath);
     UpdateFolding(document, Path.GetFileName(filepath), parseInformation);
 }