/// <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="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> /// 諜報設定を構文解析する /// </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 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> /// 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> /// 天候設定を構文解析する /// </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> /// 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> /// 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> /// 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> /// 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> /// 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> /// 外交協定設定を構文解析する /// </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> /// 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> /// ユニットを構文解析する /// </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 ScenarioHeader ParseHeader(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; } ScenarioHeader header = new ScenarioHeader(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { Log.MissingCloseBrace(LogCategory, "header", 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(); // name if (keyword.Equals("name")) { string s = ParseString(lexer); if (s == null) { Log.InvalidClause(LogCategory, "name", lexer); continue; } // シナリオヘッダ名 header.Name = s; continue; } // startdate if (keyword.Equals("startdate")) { GameDate date = ParseDate(lexer); if (date == null) { Log.InvalidSection(LogCategory, "startdate", lexer); continue; } // 開始日時 header.StartDate = date; continue; } // startyear if (keyword.Equals("startyear")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "startyear", lexer); continue; } // 開始年 header.StartYear = (int) n; continue; } // endyear if (keyword.Equals("endyear")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "endyear", lexer); continue; } // 終了年 header.EndYear = (int) n; continue; } // free if (keyword.Equals("free")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "free", lexer); continue; } // 国家の自由選択 header.IsFreeSelection = (bool) b; continue; } // combat if (keyword.Equals("combat")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "combat", lexer); continue; } // ショートシナリオ header.IsBattleScenario = (bool) b; continue; } // selectable if (keyword.Equals("selectable")) { IEnumerable<Country> list = ParseCountryList(lexer); if (list == null) { Log.InvalidSection(LogCategory, "selectable", lexer); continue; } // 選択可能国 header.SelectableCountries.AddRange(list); continue; } // set_ai_aggresive if (keyword.Equals("set_ai_aggresive")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "set_ai_aggresive", lexer); continue; } // AIの攻撃性 header.AiAggressive = (int) n; continue; } // set_difficulty if (keyword.Equals("set_difficulty")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "set_difficulty", lexer); continue; } // 難易度 header.Difficulty = (int) n; continue; } // set_gamespeed if (keyword.Equals("set_gamespeed")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "set_gamespeed", lexer); continue; } // ゲームスピード header.GameSpeed = (int) n; continue; } // 国タグ string tagName = keyword.ToUpper(); if (Countries.StringMap.ContainsKey(tagName)) { Country tag = Countries.StringMap[tagName]; if (Countries.Tags.Contains(tag)) { MajorCountrySettings major = ParseMajorCountry(lexer); if (major == null) { Log.InvalidSection(LogCategory, tagName, lexer); continue; } // 主要国設定 major.Country = tag; MajorCountrySettings prev = header.MajorCountries.FirstOrDefault(m => m.Country == tag); if (prev != null) { header.MajorCountries.Remove(prev); } header.MajorCountries.Add(major); continue; } } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return header; }
/// <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> /// IDリストを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>IDリスト</returns> private static IEnumerable<int> ParseIdList(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>(); int lastLineNo = -1; 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); if (lexer.LineNo != lastLineNo) { // 現在行が最終解釈行と異なる場合、閉じ括弧が不足しているものと見なす lexer.ReserveToken(token); break; } lexer.SkipLine(); continue; } // ID list.Add((int) (double) token.Value); // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; } 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 int? ParseInt(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.Number) { Log.InvalidToken(LogCategory, token, lexer); return null; } return (int) (double) token.Value; }
/// <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> /// 主要国情報を構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>主要国情報</returns> private static MajorCountrySettings ParseMajorCountry(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; } MajorCountrySettings major = new MajorCountrySettings(); 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(); // desc if (keyword.Equals("desc")) { string s = ParseStringOrIdentifier(lexer); if (string.IsNullOrEmpty(s)) { Log.InvalidClause(LogCategory, "desc", lexer); continue; } // 説明文 major.Desc = s; continue; } // countrytactics if (keyword.Equals("countrytactics")) { string s = ParseStringOrIdentifier(lexer); if (string.IsNullOrEmpty(s)) { Log.InvalidClause(LogCategory, "countrytactics", lexer); continue; } // 国家戦略 major.CountryTactics = s; continue; } // picture if (keyword.Equals("picture")) { string s = ParseString(lexer); if (s == null) { Log.InvalidClause(LogCategory, "picture", lexer); continue; } // プロパガンダ画像名 major.PictureName = s; continue; } // songs if (keyword.Equals("songs")) { string s = ParseString(lexer); if (s == null) { Log.InvalidClause(LogCategory, "songs", lexer); continue; } // 音楽ファイル名 major.Songs = s; continue; } // bottom if (keyword.Equals("bottom")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "bottom", lexer); continue; } // 右端に配置 major.Bottom = (bool) b; continue; } if ((Game.Type == GameType.DarkestHour) && (Game.Version >= 104)) { // name if (keyword.Equals("name")) { string s = ParseStringOrIdentifier(lexer); if (string.IsNullOrEmpty(s)) { Log.InvalidClause(LogCategory, "name", lexer); continue; } // 国名 major.Name = s; continue; } // flag_ext if (keyword.Equals("flag_ext")) { string s = ParseStringOrIdentifier(lexer); if (string.IsNullOrEmpty(s)) { Log.InvalidClause(LogCategory, "flag_ext", lexer); continue; } // 国旗接尾辞 major.FlagExt = s; continue; } } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return major; }
/// <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 MapSettings ParseMap(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; } MapSettings map = new MapSettings(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { Log.MissingCloseBrace(LogCategory, "map", 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(); // yes if (keyword.Equals("yes")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // プロヴィンスID token = lexer.GetToken(); if (token.Type == TokenType.Number) { map.Yes.Add((int) (double) token.Value); continue; } if (token.Type == TokenType.Identifier) { string s = token.Value as string; if (string.IsNullOrEmpty(s)) { continue; } s = s.ToLower(); // all if (s.Equals("all")) { map.All = true; continue; } } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); continue; } // no if (keyword.Equals("no")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // プロヴィンスID token = lexer.GetToken(); if (token.Type == TokenType.Number) { map.No.Add((int) (double) token.Value); continue; } if (token.Type == TokenType.Identifier) { string s = token.Value as string; if (string.IsNullOrEmpty(s)) { continue; } s = s.ToLower(); // all if (s.Equals("all")) { map.All = false; continue; } } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); continue; } // top if (keyword.Equals("top")) { MapPoint point = ParsePoint(lexer); if (point == null) { Log.InvalidSection(LogCategory, "top", lexer); continue; } // マップの範囲(左上) map.Top = point; continue; } // bottom if (keyword.Equals("bottom")) { MapPoint point = ParsePoint(lexer); if (point == null) { Log.InvalidSection(LogCategory, "bottom", lexer); continue; } // マップの範囲(右下) map.Bottom = point; continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return map; }
/// <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> /// 生産可能師団を構文解析する /// </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> /// 文字列値または識別子値を構文解析する /// </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> /// 任務を構文解析する /// </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 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 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> /// 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 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 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 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> /// 天候パターンを構文解析する /// </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 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セクションを構文解析する /// </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> /// 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); }