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; }
/// <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; }