Пример #1
0
        public virtual bool Parse(string text)
        {
            if (this.Disposed == true)
            {
                throw new ObjectDisposedException(this.GetType().Name);
            }

            idLexer lexer = new idLexer(idDeclFile.LexerOptions);

            lexer.LoadMemory(text, this.FileName, this.LineNumber);
            lexer.SkipUntilString("{");
            lexer.SkipBracedSection(false);

            return(true);
        }
Пример #2
0
        /// <summary>
        /// This is used during both the initial load, and any reloads.
        /// </summary>
        /// <returns></returns>
        public int LoadAndParse()
        {
            // load the text
            idConsole.DeveloperWriteLine("...loading '{0}'", this.FileName);

            byte[] data = idE.FileSystem.ReadFile(this.FileName);

            if (data == null)
            {
                idConsole.FatalError("couldn't load {0}", this.FileName);
                return(0);
            }

            string  content = UTF8Encoding.UTF8.GetString(data);
            idLexer lexer   = new idLexer();

            lexer.Options = LexerOptions;

            if (lexer.LoadMemory(content, this.FileName) == false)
            {
                idConsole.Error("Couldn't parse {0}", this.FileName);
                return(0);
            }

            // mark all the defs that were from the last reload of this file
            foreach (idDecl decl in _decls)
            {
                decl.RedefinedInReload = false;
            }

            // TODO: checksum = MD5_BlockChecksum( buffer, length );

            _fileSize = content.Length;

            int      startMarker, sourceLine;
            int      size;
            string   name;
            bool     reparse;
            idToken  token;
            idDecl   newDecl;
            DeclType identifiedType;

            string tokenValue;

            // scan through, identifying each individual declaration
            while (true)
            {
                startMarker = lexer.FileOffset;
                sourceLine  = lexer.LineNumber;

                // parse the decl type name
                if ((token = lexer.ReadToken()) == null)
                {
                    break;
                }

                tokenValue = token.ToString();

                // get the decl type from the type name
                identifiedType = idE.DeclManager.GetDeclTypeFromName(tokenValue);

                if (identifiedType == DeclType.Unknown)
                {
                    if (tokenValue == "{")
                    {
                        // if we ever see an open brace, we somehow missed the [type] <name> prefix
                        lexer.Warning("Missing decl name");
                        lexer.SkipBracedSection(false);

                        continue;
                    }
                    else
                    {
                        if (this.DefaultType == DeclType.Unknown)
                        {
                            lexer.Warning("No type");
                            continue;
                        }

                        lexer.UnreadToken = token;

                        // use the default type
                        identifiedType = this.DefaultType;
                    }
                }

                // now parse the name
                if ((token = lexer.ReadToken()) == null)
                {
                    lexer.Warning("Type without definition at the end of file");
                    break;
                }

                tokenValue = token.ToString();

                if (tokenValue == "{")
                {
                    // if we ever see an open brace, we somehow missed the [type] <name> prefix
                    lexer.Warning("Missing decl name");
                    lexer.SkipBracedSection(false);

                    continue;
                }

                // FIXME: export decls are only used by the model exporter, they are skipped here for now
                if (identifiedType == DeclType.ModelExport)
                {
                    lexer.SkipBracedSection();
                    continue;
                }

                name = tokenValue;

                // make sure there's a '{'
                if ((token = lexer.ReadToken()) == null)
                {
                    lexer.Warning("Type without definition at end of file");
                    break;
                }

                tokenValue = token.ToString();

                if (tokenValue != "{")
                {
                    lexer.Warning("Expecting '{{' but found '{0}'", tokenValue);
                    continue;
                }

                lexer.UnreadToken = token;

                // now take everything until a matched closing brace
                lexer.SkipBracedSection();
                size = lexer.FileOffset - startMarker;

                // look it up, possibly getting a newly created default decl
                reparse = false;
                newDecl = idE.DeclManager.FindTypeWithoutParsing(identifiedType, name, false);

                if (newDecl != null)
                {
                    // update the existing copy
                    if ((newDecl.SourceFile != this) || (newDecl.RedefinedInReload == true))
                    {
                        lexer.Warning("{0} '{1}' previously defined at {2}:{3}", identifiedType.ToString().ToLower(), name, newDecl.FileName, newDecl.LineNumber);
                        continue;
                    }

                    if (newDecl.State != DeclState.Unparsed)
                    {
                        reparse = true;
                    }
                }
                else
                {
                    // allow it to be created as a default, then add it to the per-file list
                    newDecl = idE.DeclManager.FindTypeWithoutParsing(identifiedType, name, true);

                    if (newDecl == null)
                    {
                        lexer.Warning("could not instanciate decl '{0}' with name '{1}'", identifiedType.ToString().ToLower(), name);
                        continue;
                    }

                    _decls.Add(newDecl);
                }

                newDecl.RedefinedInReload = true;
                newDecl.SourceText        = content.Substring(startMarker, size);
                newDecl.SourceFile        = this;
                newDecl.SourceTextOffset  = startMarker;
                newDecl.SourceTextLength  = size;
                newDecl.SourceLine        = sourceLine;
                newDecl.State             = DeclState.Unparsed;

                // if it is currently in use, reparse it immedaitely
                if (reparse)
                {
                    newDecl.ParseLocal();
                }
            }

            _lineCount = lexer.LineNumber;

            // any defs that weren't redefinedInReload should now be defaulted
            foreach (idDecl decl in _decls)
            {
                if (decl.RedefinedInReload == false)
                {
                    decl.MakeDefault();
                    decl.SourceTextOffset = decl.SourceFile.FileSize;
                    decl.SourceTextLength = 0;
                    decl.SourceLine       = decl.SourceFile.LineCount;
                }
            }

            return(_checksum);
        }