private void ParseGlobal_Expr_List(UDMFParsedMapData dataClass, ParserInfo info) { unknownGlobalAssignmentsPooled.Clear(); unknownBlocksPooled.Clear(); UDMFToken tok = scanner.LookAhead(); while (tok.Type == UDMFTokenType.IDENTIFIER) { ParseGlobal_Expr(dataClass, info); tok = scanner.LookAhead(); } if (unknownGlobalAssignmentsPooled.Count > 0) { dataClass.UnknownGlobalAssignments = new Dictionary <string, UDMFUnknownAssignment> ( unknownGlobalAssignmentsPooled, StringComparer.InvariantCultureIgnoreCase ); unknownGlobalAssignmentsPooled.Clear(); } if (unknownBlocksPooled.Count > 0) { dataClass.UnknownBlocks = new Dictionary <string, List <UDMFUnknownBlock> > (unknownBlocksPooled.Count); foreach (var kvp in unknownBlocksPooled) { var pooledList = kvp.Value; var newList = new List <UDMFUnknownBlock> (pooledList.Count); foreach (var block in pooledList) { newList.Add(block); } dataClass.UnknownBlocks.Add(kvp.Key, newList); pooledList.Clear(); pooledList.Capacity = 0; } unknownBlocksPooled.Clear(); } }
private void ParseGlobal_Expr(UDMFParsedMapData dataClass, ParserInfo info) { UDMFToken tok = scanner.Scan(); if (tok.Type != UDMFTokenType.IDENTIFIER) { Errors.Add(new UDMFParseError("Unexpected token '" + tok.Text.ToString().Replace("\n", "") + "' found. Expected " + UDMFToken.TokenTypeToString(UDMFTokenType.IDENTIFIER), 0x1001, tok)); return; } var ident = tok; var identText = namePool.GetOrCreate(ident.Text); tok = scanner.LookAhead(); switch (tok.Type) { case UDMFTokenType.BROPEN: ParserInfo.BlockInfo block; info.Blocks.TryGetValue(identText, out block); ParseBlock(dataClass, identText, block); break; case UDMFTokenType.EQSIGN: if (info.GlobalAssignments.TryGetValue(identText, out var assignment)) { ParseAssignment_Expr(dataClass, assignment); } else { var val = ParseAssignment_Expr(dataClass, null); unknownGlobalAssignmentsPooled.Add(identText, GetUnknownAssignment(val.Value)); } break; default: Errors.Add(new UDMFParseError("Unexpected token '" + tok.Text.ToString().Replace("\n", "") + "' found.", 0x0002, tok)); return; } return; }
private UDMFUnknownAssignment GetUnknownAssignment(UDMFToken tok) { var tokText = tok.Text; switch (tok.Type) { case UDMFTokenType.INTEGER: { if (!long.TryParse(tokText, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intVal)) { long.TryParse(tokText, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out intVal); } return(new UDMFUnknownAssignment(intVal)); } case UDMFTokenType.FLOAT: { double.TryParse(tokText, NumberStyles.Integer | NumberStyles.Float, CultureInfo.InvariantCulture, out var floatVal); return(new UDMFUnknownAssignment(floatVal)); } case UDMFTokenType.IDENTIFIER: { bool?boolVal = BoolFromSpan(tokText); if (boolVal.HasValue) { return(new UDMFUnknownAssignment(boolVal.Value)); } else { return(new UDMFUnknownAssignment(tok.SourceString, tok.StartPos, tok.Length, true)); } } case UDMFTokenType.QUOTED_STRING: { var newText = CleanUpQuotedString(tokText); return(new UDMFUnknownAssignment(newText, 0, newText.Length, false)); } default: throw new ArgumentException("Invalid token type.", nameof(tok)); } }
private void ParseExpr_List(IUDMFBlock block, ParserInfo.BlockInfo?info) { UDMFToken tok = scanner.LookAhead(); while (tok.Type == UDMFTokenType.IDENTIFIER) { tok = scanner.Scan(); if (tok.Type != UDMFTokenType.IDENTIFIER) { Errors.Add(new UDMFParseError("Unexpected token '" + tok.Text.ToString().Replace("\n", "") + "' found. Expected " + UDMFToken.TokenTypeToString(UDMFTokenType.IDENTIFIER), 0x1001, tok)); return; } var tokStr = namePool.GetOrCreate(tok.Text); if (info != null && info.Value.Assignments.TryGetValue(namePool.GetOrCreate(tokStr), out var assignment)) { ParseAssignment_Expr(block, assignment); } else { var val = ParseAssignment_Expr(block, null); unknownAssignmentsPooled.Add(tokStr, GetUnknownAssignment(val.Value)); } tok = scanner.LookAhead(); } if (unknownAssignmentsPooled.Count > 0) { block.UnknownAssignments = new Dictionary <string, UDMFUnknownAssignment> (StringComparer.InvariantCultureIgnoreCase); block.UnknownAssignments.EnsureCapacity(unknownAssignmentsPooled.Count); foreach (var kvp in unknownAssignmentsPooled) { block.UnknownAssignments.Add(kvp.Key, kvp.Value); } unknownAssignmentsPooled.Clear(); } }
private void ParseBlock(UDMFParsedMapData dataClass, string ident, ParserInfo.BlockInfo?info) { UDMFToken tok = scanner.Scan(); if (tok.Type != UDMFTokenType.BROPEN) { Errors.Add(new UDMFParseError("Unexpected token '" + tok.Text.ToString().Replace("\n", "") + "' found. Expected " + UDMFToken.TokenTypeToString(UDMFTokenType.BROPEN), 0x1001, tok)); return; } IUDMFBlock block; if (info != null) { block = (IUDMFBlock)Activator.CreateInstance(info.Value.BlockType); info.Value.Delegates.Getter(dataClass).AddBlock(block); } else { var newBlock = new UDMFUnknownBlock(); block = newBlock; if (!unknownBlocksPooled.TryGetValue(ident, out var unknownBlocksList)) { unknownBlocksList = new CL_PooledList <UDMFUnknownBlock> (); unknownBlocksPooled.Add(ident, unknownBlocksList); } unknownBlocksList.Add(newBlock); } ParseExpr_List(block, info); tok = scanner.Scan(); if (tok.Type != UDMFTokenType.BRCLOSE) { Errors.Add(new UDMFParseError("Unexpected token '" + tok.Text.ToString().Replace("\n", "") + "' found. Expected " + UDMFToken.TokenTypeToString(UDMFTokenType.BRCLOSE), 0x1001, tok)); return; } }
public UDMFParseError(string message, int code, UDMFToken tok) : this(message, code, tok.Line, tok.Column, tok.StartPos, tok.Length) { }
private UDMFToken?ParseAssignment_Expr(object block, ParserInfo.IAssignmentInfo data) { UDMFToken tok = scanner.Scan(); if (tok.Type != UDMFTokenType.EQSIGN) { Errors.Add(new UDMFParseError("Unexpected token '" + tok.Text.ToString().Replace("\n", "") + "' found. Expected " + UDMFToken.TokenTypeToString(UDMFTokenType.EQSIGN), 0x1001, tok)); return(null); } var valTok = scanner.Scan(); var valTokText = valTok.Text; if (data != null) { switch (Type.GetTypeCode(data.PropType)) { case TypeCode.Boolean: { bool?val = BoolFromSpan(valTokText); if (!val.HasValue) { Errors.Add(new UDMFParseError("Expected bool, got " + UDMFToken.TokenTypeToString(valTok.Type) + ".", 0x1001, valTok)); break; } SetAssignmentInfo(data, block, val.Value); } break; case TypeCode.Int32: { if (valTok.Type != UDMFTokenType.INTEGER) { Errors.Add(new UDMFParseError("Expected " + UDMFToken.TokenTypeToString(UDMFTokenType.INTEGER) + ", got " + UDMFToken.TokenTypeToString(valTok.Type) + ".", 0x1001, valTok)); break; } if (!int.TryParse(valTokText, NumberStyles.Integer, CultureInfo.InvariantCulture, out var val)) { int.TryParse(valTokText, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out val); } SetAssignmentInfo(data, block, val); } break; case TypeCode.Int64: { if (valTok.Type != UDMFTokenType.INTEGER) { Errors.Add(new UDMFParseError("Expected " + UDMFToken.TokenTypeToString(UDMFTokenType.INTEGER) + ", got " + UDMFToken.TokenTypeToString(valTok.Type) + ".", 0x1001, valTok)); break; } if (!uint.TryParse(valTokText, NumberStyles.Integer, CultureInfo.InvariantCulture, out var val)) { uint.TryParse(valTokText, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out val); } SetAssignmentInfo(data, block, val); } break; case TypeCode.UInt32: { if (valTok.Type != UDMFTokenType.INTEGER) { Errors.Add(new UDMFParseError("Expected " + UDMFToken.TokenTypeToString(UDMFTokenType.INTEGER) + ", got " + UDMFToken.TokenTypeToString(valTok.Type) + ".", 0x1001, valTok)); break; } if (!long.TryParse(valTokText, NumberStyles.Integer, CultureInfo.InvariantCulture, out var val)) { long.TryParse(valTokText, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out val); } SetAssignmentInfo(data, block, val); } break; case TypeCode.UInt64: { if (valTok.Type != UDMFTokenType.INTEGER) { Errors.Add(new UDMFParseError("Expected " + UDMFToken.TokenTypeToString(UDMFTokenType.INTEGER) + ", got " + UDMFToken.TokenTypeToString(valTok.Type) + ".", 0x1001, valTok)); break; } if (!ulong.TryParse(valTokText, NumberStyles.Integer, CultureInfo.InvariantCulture, out var val)) { ulong.TryParse(valTokText, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out val); } SetAssignmentInfo(data, block, val); } break; case TypeCode.Single: { if (valTok.Type != UDMFTokenType.FLOAT && valTok.Type != UDMFTokenType.INTEGER) { Errors.Add(new UDMFParseError("Expected " + UDMFToken.TokenTypeToString(UDMFTokenType.FLOAT) + ", got " + UDMFToken.TokenTypeToString(valTok.Type) + ".", 0x1001, valTok)); break; } float.TryParse(valTokText, NumberStyles.Integer | NumberStyles.Float, CultureInfo.InvariantCulture, out var val); SetAssignmentInfo(data, block, val); } break; case TypeCode.Double: { if (valTok.Type != UDMFTokenType.FLOAT && valTok.Type != UDMFTokenType.INTEGER) { Errors.Add(new UDMFParseError("Expected " + UDMFToken.TokenTypeToString(UDMFTokenType.FLOAT) + ", got " + UDMFToken.TokenTypeToString(valTok.Type) + ".", 0x1001, valTok)); break; } double.TryParse(valTokText, NumberStyles.Integer | NumberStyles.Float, CultureInfo.InvariantCulture, out var val); SetAssignmentInfo(data, block, val); } break; case TypeCode.String: if (valTok.Type != UDMFTokenType.QUOTED_STRING) { Errors.Add(new UDMFParseError("Expected " + UDMFToken.TokenTypeToString(UDMFTokenType.QUOTED_STRING) + ", got " + UDMFToken.TokenTypeToString(valTok.Type) + ".", 0x1001, valTok)); break; } SetAssignmentInfo(data, block, CleanUpQuotedString(valTokText)); break; default: throw new NotImplementedException(); } } tok = scanner.Scan(); if (tok.Type != UDMFTokenType.SEMICOLON) { Errors.Add(new UDMFParseError("Unexpected token '" + tok.Text.ToString().Replace("\n", "") + "' found. Expected " + UDMFToken.TokenTypeToString(UDMFTokenType.SEMICOLON), 0x1001, tok)); return(null); } return(valTok); }