/// <summary> /// minister_personalitiesセクションを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>閣僚特性リスト</returns> private static List <MinisterPersonalityInfo> ParseMinisterPersonalities(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return(null); } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return(null); } List <MinisterPersonalityInfo> list = new List <MinisterPersonalityInfo>(); while (true) { // ファイル終端 token = lexer.GetToken(); if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier || !((string)token.Value).Equals("personality")) { Log.InvalidToken(LogCategory, token, lexer); continue; } // personalityセクション MinisterPersonalityInfo info = ParseMinisterPersonality(lexer); if (info == null) { Log.InvalidSection(LogCategory, "personality", lexer); continue; } // 閣僚特性リストへ登録 list.Add(info); } return(list); }
/// <summary> /// required/or_requiredセクションを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>技術IDリスト</returns> private static IEnumerable <int> ParseRequired(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return(null); } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return(null); } List <int> list = new List <int>(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Number) { Log.InvalidToken(LogCategory, token, lexer); continue; } list.Add((int)(double)token.Value); } return(list); }
/// <summary> /// 技術ファイルを構文解析する /// </summary> /// <param name="fileName">ファイル名</param> /// <returns>技術グループデータ</returns> public static TechGroup Parse(string fileName) { using (TextLexer lexer = new TextLexer(fileName, true)) { Token token = lexer.GetToken(); // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); return(null); } string s = token.Value as string; if (string.IsNullOrEmpty(s)) { return(null); } s = s.ToLower(); // technology if (s.Equals("technology")) { TechGroup group = ParseTechnology(lexer); if (group == null) { Log.InvalidSection(LogCategory, "technology", lexer); } return(group); } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); return(null); } }
/// <summary> /// minister_modifiersセクションを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>構文解析の成否</returns> private static bool ParseMinisterModifiers(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return(false); } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return(false); } while (true) { // 暫定: 識別子を読み飛ばす token = lexer.GetToken(); if (token.Type == TokenType.Identifier) { lexer.SkipLine(); continue; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); return(false); } return(true); }
/// <summary> /// triggerセクションを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>トリガーリスト</returns> public static List<Trigger> Parse(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return null; } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return null; } return ParseContainerTrigger(lexer); }
/// <summary> /// triggerセクションを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>トリガーリスト</returns> public static List <Trigger> Parse(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return(null); } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return(null); } return(ParseContainerTrigger(lexer)); }
/// <summary> /// 閣僚特性定義ファイルを構文解析する /// </summary> /// <param name="fileName">ファイル名</param> /// <returns>閣僚特性リスト</returns> public static List <MinisterPersonalityInfo> Parse(string fileName) { List <MinisterPersonalityInfo> list = null; using (TextLexer lexer = new TextLexer(fileName, true)) { while (true) { Token token = lexer.GetToken(); // ファイルの終端 if (token == null) { return(list); } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } // minister_modifiersセクション if (keyword.Equals("minister_modifiers")) { if (!ParseMinisterModifiers(lexer)) { Log.InvalidSection(LogCategory, "minister_modifiers", lexer); } continue; } // minister_personalitiesセクション if (keyword.Equals("minister_personalities")) { list = ParseMinisterPersonalities(lexer); continue; } Log.InvalidToken(LogCategory, token, lexer); } } }
/// <summary> /// 閣僚特性定義ファイルを構文解析する /// </summary> /// <param name="fileName">ファイル名</param> /// <returns>閣僚特性リスト</returns> public static List<MinisterPersonalityInfo> Parse(string fileName) { List<MinisterPersonalityInfo> list = null; using (TextLexer lexer = new TextLexer(fileName, true)) { while (true) { Token token = lexer.GetToken(); // ファイルの終端 if (token == null) { return list; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } // minister_modifiersセクション if (keyword.Equals("minister_modifiers")) { if (!ParseMinisterModifiers(lexer)) { Log.InvalidSection(LogCategory, "minister_modifiers", lexer); } continue; } // minister_personalitiesセクション if (keyword.Equals("minister_personalities")) { list = ParseMinisterPersonalities(lexer); continue; } Log.InvalidToken(LogCategory, token, lexer); } } }
/// <summary> /// 閣僚特性定義ファイルを構文解析する /// </summary> /// <param name="fileName">ファイル名</param> /// <returns>閣僚特性リスト</returns> public static List<MinisterPersonalityInfo> Parse(string fileName) { List<MinisterPersonalityInfo> list = new List<MinisterPersonalityInfo>(); using (TextLexer lexer = new TextLexer(fileName, true)) { while (true) { Token token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // 無効なトークン if (token.Type != TokenType.Identifier || !((string) token.Value).Equals("minister")) { Log.InvalidToken(LogCategory, token, lexer); continue; } // ministerセクション MinisterPersonalityInfo info = ParseMinister(lexer); if (info == null) { Log.InvalidSection(LogCategory, "minister", lexer); } // 閣僚特性リストへ登録 list.Add(info); } return list; } }
/// <summary> /// 閣僚特性定義ファイルを構文解析する /// </summary> /// <param name="fileName">ファイル名</param> /// <returns>閣僚特性リスト</returns> public static List <MinisterPersonalityInfo> Parse(string fileName) { List <MinisterPersonalityInfo> list = new List <MinisterPersonalityInfo>(); using (TextLexer lexer = new TextLexer(fileName, true)) { while (true) { Token token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // 無効なトークン if (token.Type != TokenType.Identifier || !((string)token.Value).Equals("minister")) { Log.InvalidToken(LogCategory, token, lexer); continue; } // ministerセクション MinisterPersonalityInfo info = ParseMinister(lexer); if (info == null) { Log.InvalidSection(LogCategory, "minister", lexer); } // 閣僚特性リストへ登録 list.Add(info); } return(list); } }
/// <summary> /// modifierセクションを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>構文解析の成否</returns> private static bool ParseMinisterPersonalityModifier(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return false; } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return false; } while (true) { // ファイル終端 token = lexer.GetToken(); if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); return false; } string keyword = token.Value as string; if (keyword == null) { return false; } // type if (keyword.Equals("type")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return false; } // 識別子 token = lexer.GetToken(); if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); return false; } continue; } // value if (keyword.Equals("value")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return false; } // 識別子/数字 token = lexer.GetToken(); if (token.Type != TokenType.Identifier && token.Type != TokenType.Number) { Log.InvalidToken(LogCategory, token, lexer); return false; } continue; } // option1 if (keyword.Equals("option1")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return false; } // 数字 token = lexer.GetToken(); if (token.Type != TokenType.Number) { Log.InvalidToken(LogCategory, token, lexer); return false; } continue; } // option2 if (keyword.Equals("option2")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return false; } // 数字 token = lexer.GetToken(); if (token.Type != TokenType.Number) { Log.InvalidToken(LogCategory, token, lexer); return false; } continue; } // modifier_effect if (keyword.Equals("modifier_effect")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return false; } // 数字 token = lexer.GetToken(); if (token.Type != TokenType.Number) { Log.InvalidToken(LogCategory, token, lexer); return false; } continue; } // division if (keyword.Equals("division")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return false; } // 識別子 token = lexer.GetToken(); if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); return false; } continue; } // extra if (keyword.Equals("extra")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return false; } // 識別子 token = lexer.GetToken(); if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); return false; } continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); return false; } return true; }
/// <summary> /// minister_modifiersセクションを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>構文解析の成否</returns> private static bool ParseMinisterModifiers(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return false; } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return false; } while (true) { // 暫定: 識別子を読み飛ばす token = lexer.GetToken(); if (token.Type == TokenType.Identifier) { lexer.SkipLine(); continue; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); return false; } return true; }
/// <summary> /// セクションを構文解析する /// </summary> /// <param name="section">セクションID</param> /// <param name="type">ゲームの種類</param> /// <param name="lexer">字句解析器</param> /// <returns>構文解析の成否</returns> private static bool ParseSection(MiscSectionId section, MiscGameType type, TextLexer lexer) { // 空白文字/コメントを読み飛ばす Token token; while (true) { token = lexer.GetToken(); if (token.Type != TokenType.WhiteSpace && token.Type != TokenType.Comment) { break; } } // = if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return(false); } // 空白文字/コメントを読み飛ばす while (true) { token = lexer.GetToken(); if (token.Type != TokenType.WhiteSpace && token.Type != TokenType.Comment) { break; } } // { if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return(false); } StringBuilder sb; foreach (MiscItemId id in Misc.SectionItems[(int)section] .Where(id => Misc.ItemTable[(int)id, (int)type])) { // 空白文字/コメントを保存する sb = new StringBuilder(); while (true) { token = lexer.GetToken(); if (token.Type != TokenType.WhiteSpace && token.Type != TokenType.Comment) { break; } sb.Append(token.Value); } Misc.SetComment(id, sb.ToString()); // 設定値 if (token.Type != TokenType.Number) { Log.InvalidToken(LogCategory, token, lexer); return(false); } switch (Misc.ItemTypes[(int)id]) { case MiscItemType.Bool: Misc.SetItem(id, (int)(double)token.Value != 0); break; case MiscItemType.Enum: case MiscItemType.Int: case MiscItemType.PosInt: case MiscItemType.NonNegInt: case MiscItemType.NonPosInt: case MiscItemType.NonNegIntMinusOne: case MiscItemType.NonNegInt1: case MiscItemType.RangedInt: case MiscItemType.RangedPosInt: case MiscItemType.RangedIntMinusOne: case MiscItemType.RangedIntMinusThree: Misc.SetItem(id, (int)(double)token.Value); break; case MiscItemType.Dbl: case MiscItemType.PosDbl: case MiscItemType.NonNegDbl: case MiscItemType.NonPosDbl: case MiscItemType.NonNegDbl0: case MiscItemType.NonNegDbl2: case MiscItemType.NonNegDbl5: case MiscItemType.NonPosDbl0: case MiscItemType.NonPosDbl2: case MiscItemType.NonNegDblMinusOne: case MiscItemType.NonNegDblMinusOne1: case MiscItemType.NonNegDbl2AoD: case MiscItemType.NonNegDbl4Dda13: case MiscItemType.NonNegDbl2Dh103Full: case MiscItemType.NonNegDbl2Dh103Full1: case MiscItemType.NonNegDbl2Dh103Full2: case MiscItemType.NonPosDbl5AoD: case MiscItemType.NonPosDbl2Dh103Full: case MiscItemType.RangedDbl: case MiscItemType.RangedDblMinusOne: case MiscItemType.RangedDblMinusOne1: case MiscItemType.RangedDbl0: case MiscItemType.NonNegIntNegDbl: Misc.SetItem(id, (double)token.Value); break; } } // セクション末尾の空白文字/コメントを保存する sb = new StringBuilder(); while (true) { token = lexer.GetToken(); if (token.Type != TokenType.WhiteSpace && token.Type != TokenType.Comment) { break; } sb.Append(token.Value); } Misc.SetSuffix(section, sb.ToString()); // } (セクション終端) if (token.Type != TokenType.CloseBrace) { Log.InvalidToken(LogCategory, token, lexer); return(false); } return(true); }
/// <summary> /// eventセクションを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>技術イベントデータ</returns> private static TechEvent ParseEvent(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return(null); } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return(null); } TechEvent ev = new TechEvent(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // id if (keyword.Equals("id")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Number) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 技術イベントID ev.Id = (int)(double)token.Value; continue; } // position if (keyword.Equals("position")) { TechPosition position = ParsePosition(lexer); if (position == null) { Log.InvalidSection(LogCategory, "position", lexer); continue; } // 座標リスト ev.Positions.Add(position); continue; } // technology if (keyword.Equals("technology")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidSection(LogCategory, "technology", lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Number) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 技術ID ev.TechId = (int)(double)token.Value; continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return(ev); }
/// <summary> /// 諜報設定を構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>諜報設定</returns> private static SpySettings ParseSpyInfo(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return null; } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return null; } SpySettings spy = new SpySettings(); int lastLineNo = -1; while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // country if (keyword.Equals("country")) { Country? tag = ParseTag(lexer); if (!tag.HasValue) { Log.InvalidClause(LogCategory, "country", lexer); continue; } // 国タグ spy.Country = (Country) tag; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // numberofspies if (keyword.Equals("numberofspies")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "numberofspies", lexer); continue; } // スパイの数 spy.Spies = (int) n; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); if (lexer.LineNo != lastLineNo) { // 現在行が最終解釈行と異なる場合、閉じ括弧が不足しているものと見なす lexer.ReserveToken(token); break; } lexer.SkipLine(); } return spy; }
/// <summary> /// 保存日時を構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <param name="startDate">開始日時</param> /// <returns>保存日時</returns> private static Dictionary<int, GameDate> ParseSaveDate(TextLexer lexer, GameDate startDate) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return null; } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return null; } Dictionary<int, GameDate> dates = new Dictionary<int, GameDate>(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Number) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } int id = (int) (double) token.Value; int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, IntHelper.ToString(id), lexer); continue; } // 保存日時 GameDate date = startDate.Minus((int) n); dates[id] = date; } return dates; }
/// <summary> /// 旅団のユニット種類を構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>ユニット種類</returns> private static UnitType? ParseBrigadeType(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); return null; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); return null; } string s = token.Value as string; if (string.IsNullOrEmpty(s)) { return null; } s = s.ToLower(); // ユニットクラス名以外 if (!Units.StringMap.ContainsKey(s)) { Log.InvalidToken(LogCategory, token, lexer); return null; } // サポート外のユニット種類 UnitType type = Units.StringMap[s]; if (!Units.BrigadeTypes.Contains(type)) { Log.InvalidToken(LogCategory, token, lexer); return null; } return type; }
/// <summary> /// 生産中建物を構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>生産中建物</returns> private static BuildingDevelopment ParseBuildingDevelopment(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return null; } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return null; } BuildingDevelopment building = new BuildingDevelopment(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // id if (keyword.Equals("id")) { TypeId id = ParseTypeId(lexer); if (id == null) { Log.InvalidSection(LogCategory, "id", lexer); continue; } // typeとidの組 building.Id = id; continue; } // name if (keyword.Equals("name")) { string s = ParseString(lexer); if (s == null) { Log.InvalidClause(LogCategory, "name", lexer); continue; } // 名前 building.Name = s; continue; } // type if (keyword.Equals("type")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); continue; } string s = token.Value as string; if (string.IsNullOrEmpty(s)) { return null; } s = s.ToLower(); if (!Scenarios.BuildingStrings.Contains(s)) { // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); continue; } // 建物の種類 building.Type = (BuildingType) Array.IndexOf(Scenarios.BuildingStrings, s); continue; } // location if (keyword.Equals("location")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "location", lexer); continue; } // 位置 building.Location = (int) n; continue; } // cost if (keyword.Equals("cost")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "cost", lexer); continue; } // 必要IC building.Cost = (double) d; continue; } // manpower if (keyword.Equals("manpower")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "manpower", lexer); continue; } // 必要人的資源 building.Manpower = (double) d; continue; } // date if (keyword.Equals("date")) { GameDate date = ParseDate(lexer); if (date == null) { Log.InvalidSection(LogCategory, "date", lexer); continue; } // 完了予定日 building.Date = date; continue; } // progress if (keyword.Equals("progress")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "progress", lexer); continue; } // 進捗率増分 building.Progress = (double) d; continue; } // total_progress if (keyword.Equals("total_progress")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "total_progress", lexer); continue; } // 総進捗率 building.TotalProgress = (double) d; continue; } // gearing_bonus if (keyword.Equals("gearing_bonus")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "gearing_bonus", lexer); continue; } // 連続生産ボーナス building.GearingBonus = (double) d; continue; } // size if (keyword.Equals("size")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "size", lexer); continue; } // 総生産数 building.Size = (int) n; continue; } // done if (keyword.Equals("done")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "done", lexer); continue; } // 生産完了数 building.Done = (int) n; continue; } // days if (keyword.Equals("days")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "days", lexer); continue; } // 完了日数 building.Days = (int) n; continue; } // days_for_first if (keyword.Equals("days_for_first")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "days_for_first", lexer); continue; } // 1単位の完了日数 building.DaysForFirst = (int) n; continue; } // halted if (keyword.Equals("halted")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "halted", lexer); continue; } // 停止中 building.Halted = (bool) b; continue; } // close_when_finished if (keyword.Equals("close_when_finished")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "close_when_finished", lexer); continue; } // 完了時にキューを削除するかどうか building.CloseWhenFinished = (bool) b; continue; } // waitingforclosure if (keyword.Equals("waitingforclosure")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "waitingforclosure", lexer); continue; } // 詳細不明 building.WaitingForClosure = (bool) b; continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return building; }
/// <summary> /// modifierセクションを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>構文解析の成否</returns> private static bool ParseMinisterPersonalityModifier(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return(false); } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return(false); } while (true) { // ファイル終端 token = lexer.GetToken(); if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); return(false); } string keyword = token.Value as string; if (keyword == null) { return(false); } // type if (keyword.Equals("type")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return(false); } // 識別子 token = lexer.GetToken(); if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); return(false); } continue; } // value if (keyword.Equals("value")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return(false); } // 識別子/数字 token = lexer.GetToken(); if (token.Type != TokenType.Identifier && token.Type != TokenType.Number) { Log.InvalidToken(LogCategory, token, lexer); return(false); } continue; } // option1 if (keyword.Equals("option1")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return(false); } // 数字 token = lexer.GetToken(); if (token.Type != TokenType.Number) { Log.InvalidToken(LogCategory, token, lexer); return(false); } continue; } // option2 if (keyword.Equals("option2")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return(false); } // 数字 token = lexer.GetToken(); if (token.Type != TokenType.Number) { Log.InvalidToken(LogCategory, token, lexer); return(false); } continue; } // modifier_effect if (keyword.Equals("modifier_effect")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return(false); } // 数字 token = lexer.GetToken(); if (token.Type != TokenType.Number) { Log.InvalidToken(LogCategory, token, lexer); return(false); } continue; } // division if (keyword.Equals("division")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return(false); } // 識別子 token = lexer.GetToken(); if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); return(false); } continue; } // extra if (keyword.Equals("extra")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return(false); } // 識別子 token = lexer.GetToken(); if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); return(false); } continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); return(false); } return(true); }
/// <summary> /// personalityセクションを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>閣僚特性データ</returns> private static MinisterPersonalityInfo ParseMinisterPersonality(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return(null); } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return(null); } MinisterPersonalityInfo info = new MinisterPersonalityInfo(); while (true) { // ファイル終端 token = lexer.GetToken(); if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); return(null); } string keyword = token.Value as string; if (keyword == null) { return(null); } // personality_string if (keyword.Equals("personality_string")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.String) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 閣僚特性文字列 info.String = token.Value as string; continue; } // name if (keyword.Equals("name")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Identifier && token.Type != TokenType.String) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 閣僚特性名 info.Name = token.Value as string; continue; } // desc if (keyword.Equals("desc")) { // 暫定: 1行単位で読み飛ばす lexer.SkipLine(); continue; } // minister_position if (keyword.Equals("minister_position")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string position = token.Value as string; if (string.IsNullOrEmpty(position)) { continue; } position = position.ToLower(); // 閣僚地位 if (PositionMap.ContainsKey(position)) { // いずれか1つ info.Position[PositionMap[position]] = true; } else if (position.Equals("all")) { // 全て for (int i = 0; i < info.Position.Length; i++) { info.Position[i] = true; } } else if (Game.Type != GameType.DarkestHour || !position.Equals("generic")) { // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } continue; } // modifier if (keyword.Equals("modifier")) { if (!ParseMinisterPersonalityModifier(lexer)) { Log.InvalidSection(LogCategory, "modifier", lexer); } continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); } return(info); }
/// <summary> /// applicationセクションを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>技術データ</returns> private static TechItem ParseApplication(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return(null); } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return(null); } TechItem application = new TechItem(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // id if (keyword.Equals("id")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Number) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 技術ID application.Id = (int)(double)token.Value; continue; } // name if (keyword.Equals("name")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Identifier && token.Type != TokenType.String) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 技術名 application.Name = token.Value as string; // 短縮名 application.ShortName = "SHORT_" + application.Name; continue; } // desc if (keyword.Equals("desc")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Identifier && token.Type != TokenType.String) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 技術説明 application.Desc = token.Value as string; continue; } // position if (keyword.Equals("position")) { TechPosition position = ParsePosition(lexer); if (position == null) { Log.InvalidSection(LogCategory, "position", lexer); continue; } // 座標リスト application.Positions.Add(position); continue; } // picture if (keyword.Equals("picture")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.String) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 画像ファイル名 application.PictureName = token.Value as string; continue; } // year if (keyword.Equals("year")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Number) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 史実年 application.Year = (int)(double)token.Value; continue; } // component if (keyword.Equals("component")) { TechComponent component = ParseComponent(lexer); if (component == null) { Log.InvalidSection(LogCategory, "component", lexer); continue; } // 小研究 application.Components.Add(component); continue; } // required if (keyword.Equals("required")) { IEnumerable <int> ids = ParseRequired(lexer); if (ids == null) { Log.InvalidSection(LogCategory, "required", lexer); continue; } // 必要とする技術群(AND) foreach (int id in ids) { RequiredTech tech = new RequiredTech { Id = id }; application.AndRequiredTechs.Add(tech); } continue; } // or_required if (keyword.Equals("or_required")) { IEnumerable <int> ids = ParseRequired(lexer); if (ids == null) { Log.InvalidSection(LogCategory, "or_required", lexer); continue; } // 必要とする技術群(OR) foreach (int id in ids) { RequiredTech tech = new RequiredTech { Id = id }; application.OrRequiredTechs.Add(tech); } continue; } // effects if (keyword.Equals("effects")) { IEnumerable <Command> commands = ParseEffects(lexer); if (commands == null) { Log.InvalidSection(LogCategory, "effects", lexer); continue; } // 技術効果 application.Effects.AddRange(commands); continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return(application); }
/// <summary> /// labelセクションを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>技術ラベルデータ</returns> private static TechLabel ParseLabel(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return(null); } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return(null); } TechLabel label = new TechLabel(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // tag if (keyword.Equals("tag")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Identifier && token.Type != TokenType.String) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // タグ名 label.Name = token.Value as string; continue; } // position if (keyword.Equals("position")) { TechPosition position = ParsePosition(lexer); if (position == null) { Log.InvalidSection(LogCategory, "position", lexer); continue; } // 座標リスト label.Positions.Add(position); continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return(label); }
/// <summary> /// componentセクションを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>小研究データ</returns> private static TechComponent ParseComponent(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return(null); } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return(null); } TechComponent component = new TechComponent(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // id if (keyword.Equals("id")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Number) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 小研究ID component.Id = (int)(double)token.Value; continue; } // name if (keyword.Equals("name")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Identifier && token.Type != TokenType.String) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 小研究名 component.Name = token.Value as string; continue; } // type if (keyword.Equals("type")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効な研究特性文字列 string s = token.Value as string; if (string.IsNullOrEmpty(s)) { continue; } s = s.ToLower(); if (!Techs.SpecialityStringMap.ContainsKey(s)) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 小研究特性 component.Speciality = Techs.SpecialityStringMap[s]; continue; } // difficulty if (keyword.Equals("difficulty")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Number) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 難易度 component.Difficulty = (int)(double)token.Value; continue; } // double_time if (keyword.Equals("double_time")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string s = token.Value as string; if (string.IsNullOrEmpty(s)) { continue; } s = s.ToLower(); if (s.Equals("yes")) { // 倍の時間を要するかどうか component.DoubleTime = true; continue; } if (s.Equals("no")) { // 倍の時間を要するかどうか component.DoubleTime = false; continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return(component); }
/// <summary> /// posotionセクションを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>座標データ</returns> private static TechPosition ParsePosition(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return(null); } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return(null); } TechPosition position = new TechPosition(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // x if (keyword.Equals("x")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Number) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // X座標 position.X = (int)(double)token.Value; continue; } // y if (keyword.Equals("y")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Number) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // Y座標 position.Y = (int)(double)token.Value; continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return(position); }
/// <summary> /// 外交協定設定を構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>外交協定設定</returns> private static Treaty ParseTreaty(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return null; } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return null; } Treaty treaty = new Treaty(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // id if (keyword.Equals("id")) { TypeId id = ParseTypeId(lexer); if (id == null) { Log.InvalidSection(LogCategory, "id", lexer); continue; } // typeとidの組 treaty.Id = id; continue; } // type if (keyword.Equals("type")) { string s = ParseIdentifier(lexer); if (string.IsNullOrEmpty(s)) { Log.InvalidClause(LogCategory, "type", lexer); continue; } s = s.ToLower(); // non_aggression if (s.Equals("non_aggression")) { treaty.Type = TreatyType.NonAggression; continue; } // peace if (s.Equals("peace")) { treaty.Type = TreatyType.Peace; continue; } // trade if (s.Equals("trade")) { treaty.Type = TreatyType.Trade; continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); continue; } // country if (keyword.Equals("country")) { Country? tag = ParseTag(lexer); if (!tag.HasValue) { Log.InvalidClause(LogCategory, "country", lexer); continue; } // 対象国 if (treaty.Country1 == Country.None) { treaty.Country1 = (Country) tag; } else if (treaty.Country2 == Country.None) { treaty.Country2 = (Country) tag; } continue; } // startdate if (keyword.Equals("startdate")) { GameDate date = ParseDate(lexer); if (date == null) { Log.InvalidSection(LogCategory, "startdate", lexer); continue; } // 開始日時 treaty.StartDate = date; continue; } // expirydate if (keyword.Equals("expirydate")) { GameDate date = ParseDate(lexer); if (date == null) { Log.InvalidSection(LogCategory, "expirydate", lexer); continue; } // 失効日時 treaty.EndDate = date; continue; } // money if (keyword.Equals("money")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "money", lexer); continue; } // 資金 treaty.Money = (double) d; continue; } // supplies if (keyword.Equals("supplies")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "supplies", lexer); continue; } // 物資 treaty.Supplies = (double) d; continue; } // energy if (keyword.Equals("energy")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "energy", lexer); continue; } // エネルギー treaty.Energy = (double) d; continue; } // metal if (keyword.Equals("metal")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "metal", lexer); continue; } // 金属 treaty.Metal = (double) d; continue; } // rare_materials if (keyword.Equals("rare_materials")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "rare_materials", lexer); continue; } // 希少資源 treaty.RareMaterials = (double) d; continue; } // oil if (keyword.Equals("oil")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "oil", lexer); continue; } // 石油 treaty.Oil = (double) d; continue; } // cancel if (keyword.Equals("cancel")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "cancel", lexer); continue; } // 取り消し可能かどうか treaty.Cancel = (bool) b; continue; } if (Game.Type == GameType.ArsenalOfDemocracy) { // isoversea if (keyword.Equals("isoversea")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "isoversea", lexer); continue; } // 海外貿易かどうか treaty.IsOverSea = (bool) b; continue; } } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return treaty; }
/// <summary> /// ユニットを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <param name="branch">兵科</param> /// <returns>ユニット</returns> private static Unit ParseUnit(TextLexer lexer, Branch branch) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return null; } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return null; } Unit unit = new Unit { Branch = branch }; int lastLineNo = -1; while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // id if (keyword.Equals("id")) { TypeId id = ParseTypeId(lexer); if (id == null) { Log.InvalidSection(LogCategory, "id", lexer); continue; } // typeとidの組 unit.Id = id; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // name if (keyword.Equals("name")) { string s = ParseString(lexer); if (s == null) { Log.InvalidClause(LogCategory, "name", lexer); continue; } // ユニット名 unit.Name = s; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // control if (keyword.Equals("control")) { Country? tag = ParseTag(lexer); if (!tag.HasValue) { Log.InvalidClause(LogCategory, "control", lexer); continue; } // 統帥国 unit.Control = (Country) tag; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // leader if (keyword.Equals("leader")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "leader", lexer); continue; } // 指揮官 unit.Leader = (int) n; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // location if (keyword.Equals("location")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "location", lexer); continue; } // 現在位置 unit.Location = (int) n; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // prevprov if (keyword.Equals("prevprov")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "prevprov", lexer); continue; } // 直前の位置 unit.PrevProv = (int) n; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // home if (keyword.Equals("home")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "home", lexer); continue; } // 基準位置 unit.Home = (int) n; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // base if (keyword.Equals("base")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "base", lexer); continue; } // 所属基地 unit.Base = (int) n; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // dig_in if (keyword.Equals("dig_in")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "dig_in", lexer); continue; } // 塹壕レベル unit.DigIn = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // morale if (keyword.Equals("morale")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "morale", lexer); continue; } // 士気 unit.Morale = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // mission if (keyword.Equals("mission")) { Mission mission = ParseMission(lexer); if (mission == null) { Log.InvalidSection(LogCategory, "mission", lexer); continue; } // 任務 unit.Mission = mission; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // date if (keyword.Equals("date")) { GameDate date = ParseDate(lexer); if (date == null) { Log.InvalidSection(LogCategory, "date", lexer); continue; } // 指定日時 unit.Date = date; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // development if (keyword.Equals("development")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "development", lexer); continue; } // development (詳細不明) unit.Development = (bool) b; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // movetime if (keyword.Equals("movetime")) { GameDate date = ParseDate(lexer); if (date == null) { Log.InvalidSection(LogCategory, "movetime", lexer); continue; } // 移動完了日時 unit.MoveTime = date; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // movement if (keyword.Equals("movement")) { IEnumerable<int> list = ParseIdList(lexer); if (list == null) { Log.InvalidSection(LogCategory, "movement", lexer); continue; } // 移動経路 unit.Movement.AddRange(list); // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // attack if (keyword.Equals("attack")) { GameDate date = ParseDate(lexer); if (date == null) { Log.InvalidSection(LogCategory, "attack", lexer); continue; } // 攻撃開始日時 unit.AttackDate = date; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // invasion if (keyword.Equals("invasion")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "invasion", lexer); continue; } // 上陸中 unit.Invasion = (bool) b; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // target if (keyword.Equals("target")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "target", lexer); continue; } // 上陸先 unit.Target = (int) n; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // stand_ground if (keyword.Equals("stand_ground")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "stand_ground", lexer); continue; } // 死守命令 unit.StandGround = (bool) b; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // scorch_ground if (keyword.Equals("scorch_ground")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "scorch_ground", lexer); continue; } // 焦土作戦 unit.ScorchGround = (bool) b; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // prioritized if (keyword.Equals("prioritized")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "prioritized", lexer); continue; } // 優先 unit.Prioritized = (bool) b; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // can_upgrade if (keyword.Equals("can_upgrade")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "can_upgrade", lexer); continue; } // 改良可能 unit.CanUpgrade = (bool) b; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // can_reinforce if (keyword.Equals("can_reinforce")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "can_reinforce", lexer); continue; } // 補充可能 unit.CanReinforcement = (bool) b; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // division if (keyword.Equals("division")) { Division division = ParseDivision(lexer); if (division == null) { Log.InvalidSection(LogCategory, "division", lexer); continue; } // 兵科を設定 division.Branch = unit.Branch; // 師団 unit.Divisions.Add(division); // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // landunit if (keyword.Equals("landunit") && unit.Branch != Branch.Army) { Unit landUnit = ParseUnit(lexer, Branch.Army); if (landUnit == null) { Log.InvalidSection(LogCategory, "landunit", lexer); continue; } // 搭載ユニット unit.LandUnits.Add(landUnit); // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // strength if (keyword.Equals("strength")) { Log.InvalidToken(LogCategory, token, lexer); // strengthは師団対象であるがその後のエラー回避のため読み捨てる ParseDouble(lexer); // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // locked if (keyword.Equals("locked")) { Log.InvalidToken(LogCategory, token, lexer); // lockedは師団対象であるがその後のエラー回避のため読み捨てる ParseBool(lexer); // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); if (lexer.LineNo != lastLineNo) { // 現在行が最終解釈行と異なる場合、閉じ括弧が不足しているものと見なす lexer.ReserveToken(token); break; } lexer.SkipLine(); } return unit; }
/// <summary> /// ルール設定を構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>ルール設定</returns> private static ScenarioRules ParseRules(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return null; } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return null; } ScenarioRules rules = new ScenarioRules(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // diplomacy if (keyword.Equals("diplomacy")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "diplomacy", lexer); continue; } // 外交 rules.AllowDiplomacy = (bool) b; continue; } // production if (keyword.Equals("production")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "production", lexer); continue; } // 生産 rules.AllowProduction = (bool) b; continue; } // technology if (keyword.Equals("technology")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "technology", lexer); continue; } // 技術 rules.AllowTechnology = (bool) b; continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return rules; }
/// <summary> /// 天候設定を構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>天候設定</returns> private static Weather ParseWeather(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return null; } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return null; } Weather weather = new Weather(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // static if (keyword.Equals("static")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "static", lexer); continue; } // 固定設定 weather.Static = (bool) b; continue; } // pattern if (keyword.Equals("pattern")) { WeatherPattern pattern = ParseWeatherPattern(lexer); if (pattern == null) { Log.InvalidSection(LogCategory, "pattern", lexer); continue; } // 天候パターン weather.Patterns.Add(pattern); continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return weather; }
/// <summary> /// 建物のサイズを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>建物のサイズ</returns> private static BuildingSize ParseSize(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return null; } // 相対サイズ指定 token = lexer.GetToken(); if (token.Type == TokenType.Number) { return new BuildingSize { Size = (double) token.Value }; } // { if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return null; } BuildingSize size = new BuildingSize(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // size if (keyword.Equals("size")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "size", lexer); continue; } if (d < 0) { Log.OutOfRange(LogCategory, "size", d, lexer); continue; } // 最大サイズ size.MaxSize = (double) d; continue; } // current_size if (keyword.Equals("current_size")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "current_size", lexer); continue; } if (d < 0) { Log.OutOfRange(LogCategory, "current_size", d, lexer); continue; } // 現在サイズ size.CurrentSize = (double) d; continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return size; }
/// <summary> /// effectsセクションを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>コマンドリスト</returns> private static IEnumerable <Command> ParseEffects(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return(null); } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return(null); } List <Command> list = new List <Command>(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // command if (keyword.Equals("command")) { Command command = CommandParser.Parse(lexer); if (command == null) { Log.InvalidSection(LogCategory, "command", lexer); continue; } if (command.Type == CommandType.None) { continue; } // コマンド list.Add(command); continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return(list); }
/// <summary> /// 文字列値または識別子値を構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>文字列値</returns> private static string ParseStringOrIdentifier(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); return null; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.String && token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); return null; } return token.Value as string; }
/// <summary> /// technologyセクションを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>技術グループデータ</returns> private static TechGroup ParseTechnology(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return(null); } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return(null); } TechGroup group = new TechGroup(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // id if (keyword.Equals("id")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Number) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 技術グループID group.Id = (int)(double)token.Value; continue; } // category if (keyword.Equals("category")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なカテゴリ文字列 string s = token.Value as string; if (string.IsNullOrEmpty(s)) { continue; } if (!Techs.CategoryMap.ContainsKey(s)) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 技術カテゴリ group.Category = Techs.CategoryMap[s]; continue; } // name if (keyword.Equals("name")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Identifier && token.Type != TokenType.String) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 技術グループ名 group.Name = token.Value as string; continue; } // desc if (keyword.Equals("desc")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Identifier && token.Type != TokenType.String) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 技術グループ説明 group.Desc = token.Value as string; continue; } // label if (keyword.Equals("label")) { TechLabel label = ParseLabel(lexer); if (label == null) { Log.InvalidSection(LogCategory, "label", lexer); continue; } // ラベル group.Items.Add(label); continue; } // event if (keyword.Equals("event")) { TechEvent ev = ParseEvent(lexer); if (ev == null) { Log.InvalidSection(LogCategory, "event", lexer); continue; } // 技術イベント group.Items.Add(ev); continue; } // application if (keyword.Equals("application")) { TechItem application = ParseApplication(lexer); if (application == null) { Log.InvalidSection(LogCategory, "application", lexer); continue; } // 技術 group.Items.Add(application); continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return(group); }
/// <summary> /// 国タグを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>国タグ</returns> private static Country? ParseTag(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); return null; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.String && token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); return null; } string name = token.Value as string; if (string.IsNullOrEmpty(name)) { return null; } name = name.ToUpper(); if (!Countries.StringMap.ContainsKey(name)) { Log.InvalidToken(LogCategory, token, lexer); return null; } Country tag = Countries.StringMap[name]; if (!Countries.Tags.Contains(tag)) { Log.InvalidToken(LogCategory, token, lexer); return null; } return tag; }
/// <summary> /// 生産可能師団を構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>生産可能師団</returns> private static Dictionary<UnitType, bool> ParseAllowedDivisions(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return null; } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return null; } Dictionary<UnitType, bool> divisions = new Dictionary<UnitType, bool>(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string s = token.Value as string; if (string.IsNullOrEmpty(s)) { return null; } s = s.ToLower(); // ユニットクラス名以外 if (!Units.StringMap.ContainsKey(s)) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // サポート外のユニット種類 UnitType type = Units.StringMap[s]; if (!Units.DivisionTypes.Contains(type)) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "allowed_divisions", lexer); lexer.SkipLine(); continue; } divisions[type] = (bool) b; } return divisions; }
/// <summary> /// typeとidの組を構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>typeとidの組</returns> private static TypeId ParseTypeId(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return null; } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return null; } TypeId id = new TypeId(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // type if (keyword.Equals("type")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "type", lexer); continue; } // type id.Type = (int) n; continue; } // id if (keyword.Equals("id")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "id", lexer); continue; } // id id.Id = (int) n; continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return id; }
/// <summary> /// 任務を構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>任務</returns> private static Mission ParseMission(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return null; } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return null; } Mission mission = new Mission(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // type if (keyword.Equals("type")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); continue; } string s = token.Value as string; if (string.IsNullOrEmpty(s)) { return null; } s = s.ToLower(); if (!Scenarios.MissionStrings.Contains(s)) { // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); continue; } // 任務の種類 mission.Type = (MissionType) Array.IndexOf(Scenarios.MissionStrings, s); continue; } // target if (keyword.Equals("target")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "target", lexer); continue; } // 対象プロヴィンス mission.Target = (int) n; continue; } // missionscope if (keyword.Equals("missionscope")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "missionscope", lexer); continue; } // 対象範囲 mission.MissionScope = (int) n; continue; } // percentage if (keyword.Equals("percentage")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "percentage", lexer); continue; } // 戦力/指揮統制率下限 mission.Percentage = (double) d; continue; } // night if (keyword.Equals("night")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "night", lexer); continue; } // 夜間遂行 mission.Night = (bool) b; continue; } // day if (keyword.Equals("day")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "day", lexer); continue; } // 昼間遂行 mission.Day = (bool) b; continue; } // tz if (keyword.Equals("tz")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "tz", lexer); continue; } // 対象範囲 mission.TargetZone = (int) n; continue; } // ac if (keyword.Equals("ac")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "ac", lexer); continue; } // 船団攻撃 mission.AttackConvoy = (bool) b; continue; } // org if (keyword.Equals("org")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "org", lexer); continue; } // 組織率下限 mission.OrgLimit = (double) d; continue; } // startdate if (keyword.Equals("startdate")) { GameDate date = ParseDate(lexer); if (date == null) { Log.InvalidSection(LogCategory, "startdate", lexer); continue; } // 開始日時 mission.StartDate = date; continue; } // enddate if (keyword.Equals("enddate")) { GameDate date = ParseDate(lexer); if (date == null) { Log.InvalidSection(LogCategory, "enddate", lexer); continue; } // 終了日時 mission.EndDate = date; continue; } // task if (keyword.Equals("task")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "task", lexer); continue; } // 任務 mission.Task = (int) n; continue; } // location if (keyword.Equals("location")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "location", lexer); continue; } // 位置 mission.Location = (int) n; continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return mission; }
/// <summary> /// 戦争設定を構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>戦争設定</returns> private static War ParseWar(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return null; } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return null; } War war = new War(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // id if (keyword.Equals("id")) { TypeId id = ParseTypeId(lexer); if (id == null) { Log.InvalidSection(LogCategory, "id", lexer); continue; } // typeとidの組 war.Id = id; continue; } // date if (keyword.Equals("date")) { GameDate date = ParseDate(lexer); if (date == null) { Log.InvalidSection(LogCategory, "date", lexer); continue; } // 開始日時 war.StartDate = date; continue; } // enddate if (keyword.Equals("enddate")) { GameDate date = ParseDate(lexer); if (date == null) { Log.InvalidSection(LogCategory, "enddate", lexer); continue; } // 終了日時 war.EndDate = date; continue; } // attackers if (keyword.Equals("attackers")) { Alliance alliance = ParseAlliance(lexer); if (alliance == null) { Log.InvalidSection(LogCategory, "attackers", lexer); continue; } // 攻撃側参加国 war.Attackers = alliance; continue; } // defenders if (keyword.Equals("defenders")) { Alliance alliance = ParseAlliance(lexer); if (alliance == null) { Log.InvalidSection(LogCategory, "defenders", lexer); continue; } // 防御側参加国 war.Defenders = alliance; continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return war; }
/// <summary> /// マップの座標を構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>マップの座標</returns> private static MapPoint ParsePoint(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return null; } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return null; } MapPoint point = new MapPoint(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // x if (keyword.Equals("x")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "x", lexer); continue; } // X座標 point.X = (int) n; continue; } // y if (keyword.Equals("y")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "y", lexer); continue; } // Y座標 point.Y = (int) n; continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return point; }
/// <summary> /// 天候パターンを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>天候パターン</returns> private static WeatherPattern ParseWeatherPattern(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return null; } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return null; } WeatherPattern pattern = new WeatherPattern(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // id if (keyword.Equals("id")) { TypeId id = ParseTypeId(lexer); if (id == null) { Log.InvalidSection(LogCategory, "id", lexer); continue; } // typeとidの組 pattern.Id = id; continue; } // provinces if (keyword.Equals("provinces")) { IEnumerable<int> list = ParseIdList(lexer); if (list == null) { Log.InvalidSection(LogCategory, "provinces", lexer); continue; } // プロヴィンスリスト pattern.Provinces.AddRange(list); continue; } // centre if (keyword.Equals("centre")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "centre", lexer); continue; } // 中央プロヴィンス pattern.Centre = (int) n; continue; } // speed if (keyword.Equals("speed")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "speed", lexer); continue; } // 速度 pattern.Speed = (int) n; continue; } // heading if (keyword.Equals("heading")) { string s = ParseString(lexer); if (s == null) { Log.InvalidClause(LogCategory, "heading", lexer); continue; } // 方向 pattern.Heading = s; continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return pattern; }
/// <summary> /// 政策スライダーを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>政策スライダー</returns> private static CountryPolicy ParsePolicy(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return null; } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return null; } CountryPolicy policy = new CountryPolicy(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // date if (keyword.Equals("date")) { GameDate date = ParseDate(lexer); if (date == null) { Log.InvalidSection(LogCategory, "date", lexer); continue; } // スライダー移動可能日時 policy.Date = date; continue; } // democratic if (keyword.Equals("democratic")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "democratic", lexer); continue; } if (n < 1 || n > 10) { Log.OutOfRange(LogCategory, "democratic", n, lexer); continue; } // 民主的 - 独裁的 policy.Democratic = (int) n; continue; } // political_left if (keyword.Equals("political_left")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "political_left", lexer); continue; } if (n < 1 || n > 10) { Log.OutOfRange(LogCategory, "political_left", n, lexer); continue; } // 政治的左派 - 政治的右派 policy.PoliticalLeft = (int) n; continue; } // freedom if (keyword.Equals("freedom")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "freedom", lexer); continue; } if (n < 1 || n > 10) { Log.OutOfRange(LogCategory, "freedom", n, lexer); continue; } // 開放社会 - 閉鎖社会 policy.Freedom = (int) n; continue; } // free_market if (keyword.Equals("free_market")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "freedom", lexer); continue; } if (n < 1 || n > 10) { Log.OutOfRange(LogCategory, "freedom", n, lexer); continue; } // 自由経済 - 中央計画経済 policy.FreeMarket = (int) n; continue; } // professional_army if (keyword.Equals("professional_army")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "professional_army", lexer); continue; } if (n < 1 || n > 10) { Log.OutOfRange(LogCategory, "professional_army", n, lexer); continue; } // 常備軍 - 徴兵軍 (DH Fullでは動員 - 復員) policy.ProfessionalArmy = (int) n; continue; } // defense_lobby if (keyword.Equals("defense_lobby")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "defense_lobby", lexer); continue; } if (n < 1 || n > 10) { Log.OutOfRange(LogCategory, "defense_lobby", n, lexer); continue; } // タカ派 - ハト派 policy.DefenseLobby = (int) n; continue; } // interventionism if (keyword.Equals("interventionism")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "interventionism", lexer); continue; } if (n < 1 || n > 10) { Log.OutOfRange(LogCategory, "interventionism", n, lexer); continue; } // 介入主義 - 孤立主義 policy.Interventionism = (int) n; continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return policy; }
/// <summary> /// トリガーのコンテナを構文解析する /// </summary> /// <param name="lexer"></param> /// <returns></returns> private static List <Trigger> ParseContainerTrigger(TextLexer lexer) { List <Trigger> list = new List <Trigger>(); int lastLineNo = lexer.LineNo; while (true) { Token token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); if (lexer.LineNo != lastLineNo) { // 現在行が最終解釈行と異なる場合、閉じ括弧が不足しているものと見なす lexer.ReserveToken(token); break; } continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // 無効なキーワード if (!TypeMap.ContainsKey(keyword)) { Log.InvalidToken(LogCategory, token, lexer); if (lexer.LineNo != lastLineNo) { // 現在行が最終解釈行と異なる場合、閉じ括弧が不足しているものと見なす lexer.ReserveToken(token); break; } continue; } Trigger trigger = new Trigger { Type = TypeMap[keyword] }; // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); continue; } token = lexer.GetToken(); if (token.Type == TokenType.OpenBrace) { List <Trigger> triggers = ParseContainerTrigger(lexer); if (triggers == null) { continue; } trigger.Value = triggers; list.Add(trigger); // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } if (token.Type != TokenType.Number && token.Type != TokenType.Identifier && token.Type != TokenType.String) { Log.InvalidToken(LogCategory, token, lexer); if (lexer.LineNo != lastLineNo) { // 現在行が最終解釈行と異なる場合、閉じ括弧が不足しているものと見なす lexer.ReserveToken(token); break; } continue; } trigger.Value = token.Value; list.Add(trigger); // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; } return(list.Count > 0 ? list : null); }
/// <summary> /// プロヴィンス設定を構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>プロヴィンス設定</returns> private static ProvinceSettings ParseProvince(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return null; } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return null; } ProvinceSettings province = new ProvinceSettings(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { Log.MissingCloseBrace(LogCategory, "province", lexer); break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // id if (keyword.Equals("id")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "id", lexer); continue; } // プロヴィンスID province.Id = (int) n; continue; } // ic if (keyword.Equals("ic")) { BuildingSize size = ParseSize(lexer); if (size == null) { Log.InvalidSection(LogCategory, "ic", lexer); continue; } // IC province.Ic = size; continue; } // infra if (keyword.Equals("infra")) { BuildingSize size = ParseSize(lexer); if (size == null) { Log.InvalidSection(LogCategory, "infra", lexer); continue; } // インフラ province.Infrastructure = size; continue; } // landfort if (keyword.Equals("landfort")) { BuildingSize size = ParseSize(lexer); if (size == null) { Log.InvalidSection(LogCategory, "landfort", lexer); continue; } // 陸上要塞 province.LandFort = size; continue; } // coastalfort if (keyword.Equals("coastalfort")) { BuildingSize size = ParseSize(lexer); if (size == null) { Log.InvalidSection(LogCategory, "coastalfort", lexer); continue; } // 沿岸要塞 province.CoastalFort = size; continue; } // anti_air if (keyword.Equals("anti_air")) { BuildingSize size = ParseSize(lexer); if (size == null) { Log.InvalidSection(LogCategory, "anti_air", lexer); continue; } // 対空砲 province.AntiAir = size; continue; } // air_base if (keyword.Equals("air_base")) { BuildingSize size = ParseSize(lexer); if (size == null) { Log.InvalidSection(LogCategory, "air_base", lexer); continue; } // 空軍基地 province.AirBase = size; continue; } // naval_base if (keyword.Equals("naval_base")) { BuildingSize size = ParseSize(lexer); if (size == null) { Log.InvalidSection(LogCategory, "naval_base", lexer); continue; } // 海軍基地 province.NavalBase = size; continue; } // radar_station if (keyword.Equals("radar_station")) { BuildingSize size = ParseSize(lexer); if (size == null) { Log.InvalidSection(LogCategory, "radar_station", lexer); continue; } // レーダー基地 province.RadarStation = size; continue; } // nuclear_reactor if (keyword.Equals("nuclear_reactor")) { BuildingSize size = ParseSize(lexer); if (size == null) { Log.InvalidSection(LogCategory, "nuclear_reactor", lexer); continue; } // 原子炉 province.NuclearReactor = size; continue; } // rocket_test if (keyword.Equals("rocket_test")) { BuildingSize size = ParseSize(lexer); if (size == null) { Log.InvalidSection(LogCategory, "rocket_test", lexer); continue; } // ロケット試験場 province.RocketTest = size; continue; } // synthetic_oil if (keyword.Equals("synthetic_oil")) { BuildingSize size = ParseSize(lexer); if (size == null) { Log.InvalidSection(LogCategory, "synthetic_oil", lexer); continue; } // 合成石油工場 province.SyntheticOil = size; continue; } // synthetic_rares if (keyword.Equals("synthetic_rares")) { BuildingSize size = ParseSize(lexer); if (size == null) { Log.InvalidSection(LogCategory, "synthetic_rares", lexer); continue; } // 合成素材工場 province.SyntheticRares = size; continue; } // nuclear_power if (keyword.Equals("nuclear_power")) { BuildingSize size = ParseSize(lexer); if (size == null) { Log.InvalidSection(LogCategory, "nuclear_power", lexer); continue; } // 原子力発電所 province.NuclearPower = size; continue; } // supplypool if (keyword.Equals("supplypool")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "supplypool", lexer); continue; } // 物資の備蓄量 province.SupplyPool = (double) d; continue; } // oilpool if (keyword.Equals("oilpool")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "oilpool", lexer); continue; } // 石油の備蓄量 province.OilPool = (double) d; continue; } // energypool if (keyword.Equals("energypool")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "energypool", lexer); continue; } // エネルギーの備蓄量 province.EnergyPool = (double) d; continue; } // metalpool if (keyword.Equals("metalpool")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "metalpool", lexer); continue; } // 金属の備蓄量 province.MetalPool = (double) d; continue; } // rarematerialspool if (keyword.Equals("rarematerialspool")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "rarematerialspool", lexer); continue; } // 希少資源の備蓄量 province.RareMaterialsPool = (double) d; continue; } // energy if (keyword.Equals("energy")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "energy", lexer); continue; } // エネルギー産出量 province.Energy = (double) d; continue; } // max_energy if (keyword.Equals("max_energy")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "max_energy", lexer); continue; } // 最大エネルギー産出量 province.MaxEnergy = (double) d; continue; } // metal if (keyword.Equals("metal")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "metal", lexer); continue; } // 金属産出量 province.Metal = (double) d; continue; } // max_metal if (keyword.Equals("max_metal")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "max_metal", lexer); continue; } // 最大金属産出量 province.MaxMetal = (double) d; continue; } // rare_materials if (keyword.Equals("rare_materials")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "rare_materials", lexer); continue; } // 希少資源産出量 province.RareMaterials = (double) d; continue; } // max_rare_materials if (keyword.Equals("max_rare_materials")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "max_rare_materials", lexer); continue; } // 最大希少資源産出量 province.MaxRareMaterials = (double) d; continue; } // oil if (keyword.Equals("oil")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "oil", lexer); continue; } // 石油産出量 province.Oil = (double) d; continue; } // max_oil if (keyword.Equals("max_oil")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "max_oil", lexer); continue; } // 最大石油産出量 province.MaxOil = (double) d; continue; } // manpower if (keyword.Equals("manpower")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "manpower", lexer); continue; } // 人的資源 province.Manpower = (double) d; continue; } // max_manpower if (keyword.Equals("max_manpower")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "max_manpower", lexer); continue; } // 最大人的資源 province.MaxManpower = (double) d; continue; } // points if (keyword.Equals("points")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "points", lexer); continue; } // 勝利ポイント province.Vp = (int) n; continue; } // province_revoltrisk if (keyword.Equals("province_revoltrisk")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "province_revoltrisk", lexer); continue; } // 反乱率 province.RevoltRisk = (double) d; continue; } // weather if (keyword.Equals("weather")) { string s = ParseIdentifier(lexer); if (string.IsNullOrEmpty(s)) { continue; } s = s.ToLower(); if (!Scenarios.WeatherStrings.Contains(s)) { Log.InvalidToken(LogCategory, token, lexer); continue; } // 天候 province.Weather = (WeatherType) Array.IndexOf(Scenarios.WeatherStrings, s); continue; } if (Game.Type == GameType.DarkestHour) { // name if (keyword.Equals("name")) { string s = ParseStringOrIdentifier(lexer); if (string.IsNullOrEmpty(s)) { Log.InvalidClause(LogCategory, "name", lexer); continue; } // プロヴィンス名 province.Name = s; continue; } } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return province; }
/// <summary> /// miscファイルを構文解析する /// </summary> /// <param name="fileName">ファイル名</param> public static void Parse(string fileName) { // ゲームの種類を設定する MiscGameType type = Misc.GetGameType(); using (TextLexer lexer = new TextLexer(fileName, false)) { while (true) { Token token = lexer.GetToken(); // ファイルの終端 if (token == null) { return; } // 空白文字/コメントを読み飛ばす if (token.Type == TokenType.WhiteSpace || token.Type == TokenType.Comment) { continue; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } // economyセクション if (keyword.Equals("economy")) { if (!ParseSection(MiscSectionId.Economy, type, lexer)) { Log.InvalidSection(LogCategory, "economy", lexer); } continue; } // intelligenceセクション if (keyword.Equals("intelligence")) { if (!ParseSection(MiscSectionId.Intelligence, type, lexer)) { Log.InvalidSection(LogCategory, "intelligence", lexer); } continue; } // diplomacyセクション if (keyword.Equals("diplomacy")) { if (!ParseSection(MiscSectionId.Diplomacy, type, lexer)) { Log.InvalidSection(LogCategory, "diplomacy", lexer); } continue; } // combatセクション if (keyword.Equals("combat")) { if (!ParseSection(MiscSectionId.Combat, type, lexer)) { Log.InvalidSection(LogCategory, "combat", lexer); } continue; } // missionセクション if (keyword.Equals("mission")) { if (!ParseSection(MiscSectionId.Mission, type, lexer)) { Log.InvalidSection(LogCategory, "mission", lexer); } continue; } // countryセクション if (keyword.Equals("country")) { if (!ParseSection(MiscSectionId.Country, type, lexer)) { Log.InvalidSection(LogCategory, "country", lexer); } continue; } // researchセクション if (keyword.Equals("research")) { if (!ParseSection(MiscSectionId.Research, type, lexer)) { Log.InvalidSection(LogCategory, "research", lexer); } continue; } // tradeセクション if (keyword.Equals("trade")) { if (!ParseSection(MiscSectionId.Trade, type, lexer)) { Log.InvalidSection(LogCategory, "trade", lexer); } continue; } // aiセクション if (keyword.Equals("ai")) { if (!ParseSection(MiscSectionId.Ai, type, lexer)) { Log.InvalidSection(LogCategory, "ai", lexer); } continue; } // modセクション if (keyword.Equals("mod")) { if (!ParseSection(MiscSectionId.Mod, type, lexer)) { Log.InvalidSection(LogCategory, "mod", lexer); } continue; } // mapセクション if (keyword.Equals("map")) { if (!ParseSection(MiscSectionId.Map, type, lexer)) { Log.InvalidSection(LogCategory, "map", lexer); } continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); } } }
/// <summary> /// ブール値を構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>ブール値</returns> private static bool? ParseBool(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); return null; } // 無効なトークン token = lexer.GetToken(); if (token.Type == TokenType.Identifier) { string s = token.Value as string; if (string.IsNullOrEmpty(s)) { return null; } s = s.ToLower(); // yes if (s.Equals("yes")) { return true; } // no if (s.Equals("no")) { return false; } } else if (token.Type == TokenType.Number) { int n = (int) (double) token.Value; if (n == 1) { return true; } if (n == 0) { return false; } } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); return null; }
/// <summary> /// minister_personalitiesセクションを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>閣僚特性リスト</returns> private static List<MinisterPersonalityInfo> ParseMinisterPersonalities(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return null; } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return null; } List<MinisterPersonalityInfo> list = new List<MinisterPersonalityInfo>(); while (true) { // ファイル終端 token = lexer.GetToken(); if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier || !((string) token.Value).Equals("personality")) { Log.InvalidToken(LogCategory, token, lexer); continue; } // personalityセクション MinisterPersonalityInfo info = ParseMinisterPersonality(lexer); if (info == null) { Log.InvalidSection(LogCategory, "personality", lexer); continue; } // 閣僚特性リストへ登録 list.Add(info); } return list; }
/// <summary> /// 処理待ちイベントを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>処理待ちイベント</returns> private static QueuedEvent ParseQueuedEvent(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return null; } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return null; } QueuedEvent qe = new QueuedEvent(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // tag if (keyword.Equals("tag")) { Country? tag = ParseTag(lexer); if (!tag.HasValue) { Log.InvalidClause(LogCategory, "tag", lexer); continue; } // イベント発生国 qe.Country = (Country) tag; continue; } // id if (keyword.Equals("id")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "id", lexer); continue; } // イベントID qe.Id = (int) n; continue; } // hour if (keyword.Equals("hour")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "hour", lexer); continue; } // イベント発生待ち時間 qe.Hour = (int) n; continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return qe; }
/// <summary> /// 処理待ちイベントリストを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>処理待ちイベントリスト</returns> private static List<QueuedEvent> ParseQueuedEvents(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return null; } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return null; } List<QueuedEvent> list = new List<QueuedEvent>(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // event if (keyword.Equals("event")) { QueuedEvent qe = ParseQueuedEvent(lexer); if (qe == null) { Log.InvalidSection(LogCategory, "event", lexer); continue; } // 処理待ちイベント list.Add(qe); continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return list; }
/// <summary> /// 外交関係設定を構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>外交関係情報</returns> private static Relation ParseRelation(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return null; } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return null; } Relation relation = new Relation(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // tag if (keyword.Equals("tag")) { Country? tag = ParseTag(lexer); if (!tag.HasValue) { Log.InvalidClause(LogCategory, "tag", lexer); continue; } // 国タグ relation.Country = (Country) tag; continue; } // value if (keyword.Equals("value")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "value", lexer); continue; } // 関係値 relation.Value = (double) d; continue; } // access if (keyword.Equals("access")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "access", lexer); continue; } // 通行許可 relation.Access = (bool) b; continue; } // guaranteed if (keyword.Equals("guaranteed")) { GameDate date = ParseDate(lexer); if (date == null) { Log.InvalidSection(LogCategory, "guaranteed", lexer); continue; } // 独立保障期限 relation.Guaranteed = date; continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return relation; }
/// <summary> /// ministerセクションを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>閣僚特性データ</returns> private static MinisterPersonalityInfo ParseMinister(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return null; } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return null; } MinisterPersonalityInfo info = new MinisterPersonalityInfo(); while (true) { // ファイル終端 token = lexer.GetToken(); if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); return null; } string keyword = token.Value as string; if (keyword == null) { return null; } // trait if (keyword.Equals("trait")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.String) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 閣僚特性文字列 info.String = token.Value as string; continue; } // id if (keyword.Equals("id")) { // 暫定: 1行単位で読み飛ばす lexer.SkipLine(); continue; } // name if (keyword.Equals("name")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Identifier && token.Type != TokenType.String) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 閣僚特性名 info.Name = token.Value as string; continue; } // desc if (keyword.Equals("desc")) { // 暫定: 1行単位で読み飛ばす lexer.SkipLine(); continue; } // position if (keyword.Equals("position")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string position = token.Value as string; if (string.IsNullOrEmpty(position)) { continue; } position = position.ToLower(); // 閣僚地位 if (PositionMap.ContainsKey(position)) { // いずれか1つ info.Position[PositionMap[position]] = true; } else if (position.Equals("all")) { // 全て for (int i = 0; i < info.Position.Length; i++) { info.Position[i] = true; } } else if (!position.Equals("generic")) { // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } continue; } // value if (keyword.Equals("value")) { // 暫定: 1行単位で読み飛ばす lexer.SkipLine(); continue; } // command if (keyword.Equals("command")) { // 暫定: 1行単位で読み飛ばす lexer.SkipLine(); //continue; } } return info; }
/// <summary> /// commandセクションを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>コマンド</returns> public static Command Parse(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return(null); } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return(null); } Command command = new Command(); int lastLineNo = lexer.LineNo; while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); if (lexer.LineNo != lastLineNo) { // 現在行が最終解釈行と異なる場合、閉じ括弧が不足しているものと見なす lexer.ReserveToken(token); break; } continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // type if (keyword.Equals("type")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); continue; } // 無効なコマンド種類文字列 string s = token.Value as string; if (string.IsNullOrEmpty(s)) { continue; } s = s.ToLower(); if (!Commands.StringMap.ContainsKey(s)) { Log.InvalidToken(LogCategory, token, lexer); continue; } // コマンド種類 command.Type = Commands.StringMap[s]; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // which if (keyword.Equals("which")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Number && token.Type != TokenType.Identifier && token.Type != TokenType.String) { Log.InvalidToken(LogCategory, token, lexer); continue; } // パラメータ - which command.Which = token.Value; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // value if (keyword.Equals("value")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Number && token.Type != TokenType.Identifier && token.Type != TokenType.String) { Log.InvalidToken(LogCategory, token, lexer); continue; } // パラメータ - value command.Value = token.Value; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // when if (keyword.Equals("when")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Number && token.Type != TokenType.Identifier && token.Type != TokenType.String) { Log.InvalidToken(LogCategory, token, lexer); continue; } // パラメータ - when command.When = token.Value; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // where if (keyword.Equals("where")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Number && token.Type != TokenType.Identifier && token.Type != TokenType.String) { Log.InvalidToken(LogCategory, token, lexer); continue; } // パラメータ - where command.Where = token.Value; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // trigger if (keyword.Equals("trigger")) { List <Trigger> triggers = TriggerParser.Parse(lexer); if (triggers == null) { continue; } // トリガー command.Triggers.AddRange(triggers); // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); if (lexer.LineNo != lastLineNo) { // 現在行が最終解釈行と異なる場合、閉じ括弧が不足しているものと見なす lexer.ReserveToken(token); break; } } return(command); }