/// <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 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="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 DivisionDevelopment ParseDivisionDevelopment(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; } DivisionDevelopment division = new DivisionDevelopment(); 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の組 division.Id = id; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // name if (keyword.Equals("name")) { string s = ParseString(lexer); if (s == null) { Log.InvalidClause(LogCategory, "name", lexer); continue; } // 師団名 division.Name = s; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // cost if (keyword.Equals("cost")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "cost", lexer); continue; } // 必要IC division.Cost = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // manpower if (keyword.Equals("manpower")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "manpower", lexer); continue; } // 必要人的資源 division.Manpower = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // unitcost if (keyword.Equals("unitcost")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "unitcost", lexer); continue; } // unitcost division.UnitCost = (bool) b; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // new_model if (keyword.Equals("new_model")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "unitcost", lexer); continue; } // new_model division.NewModel = (bool) b; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // date if (keyword.Equals("date")) { GameDate date = ParseDate(lexer); if (date == null) { Log.InvalidSection(LogCategory, "date", lexer); continue; } // 完了予定日 division.Date = date; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // progress if (keyword.Equals("progress")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "progress", lexer); continue; } // 進捗率増分 division.Progress = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // total_progress if (keyword.Equals("total_progress")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "total_progress", lexer); continue; } // 総進捗率 division.TotalProgress = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // gearing_bonus if (keyword.Equals("gearing_bonus")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "gearing_bonus", lexer); continue; } // 連続生産ボーナス division.GearingBonus = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // size if (keyword.Equals("size")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "size", lexer); continue; } // 総生産数 division.Size = (int) n; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // done if (keyword.Equals("done")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "done", lexer); continue; } // 生産完了数 division.Done = (int) n; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // days if (keyword.Equals("days")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "days", lexer); continue; } // 完了日数 division.Days = (int) n; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; 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単位の完了日数 division.DaysForFirst = (int) n; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // halted if (keyword.Equals("halted")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "halted", lexer); continue; } // 停止中 division.Halted = (bool) b; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; 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; } // 完了時にキューを削除するかどうか division.CloseWhenFinished = (bool) b; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // waitingforclosure if (keyword.Equals("waitingforclosure")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "waitingforclosure", lexer); continue; } // waitingforclosure (詳細不明) division.WaitingForClosure = (bool) b; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // retooling_time if (keyword.Equals("retooling_time")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "retooling_time", lexer); continue; } // 生産ライン準備時間 division.RetoolingTime = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // type if (keyword.Equals("type")) { UnitType? type = ParseDivisionType(lexer); if (type == null) { Log.InvalidClause(LogCategory, "type", lexer); continue; } // ユニット種類 division.Type = (UnitType) type; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // model if (keyword.Equals("model")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "model", lexer); continue; } // モデル番号 division.Model = (int) n; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // extra if (keyword.Equals("extra")) { UnitType? type = ParseBrigadeType(lexer); if (type == null) { Log.InvalidClause(LogCategory, "extra", lexer); continue; } // 付属旅団のユニット種類 division.Extra1 = (UnitType) type; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // extra1 if (keyword.Equals("extra1")) { UnitType? type = ParseBrigadeType(lexer); if (type == null) { Log.InvalidClause(LogCategory, "extra1", lexer); continue; } // 付属旅団のユニット種類 division.Extra1 = (UnitType) type; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // extra2 if (keyword.Equals("extra2")) { UnitType? type = ParseBrigadeType(lexer); if (type == null) { Log.InvalidClause(LogCategory, "extra2", lexer); continue; } // 付属旅団のユニット種類 division.Extra2 = (UnitType) type; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // extra3 if (keyword.Equals("extra3")) { UnitType? type = ParseBrigadeType(lexer); if (type == null) { Log.InvalidClause(LogCategory, "extra3", lexer); continue; } // 付属旅団のユニット種類 division.Extra3 = (UnitType) type; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // extra4 if (keyword.Equals("extra4")) { UnitType? type = ParseBrigadeType(lexer); if (type == null) { Log.InvalidClause(LogCategory, "extra4", lexer); continue; } // 付属旅団のユニット種類 division.Extra4 = (UnitType) type; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // extra5 if (keyword.Equals("extra5")) { UnitType? type = ParseBrigadeType(lexer); if (type == null) { Log.InvalidClause(LogCategory, "extra5", lexer); continue; } // 付属旅団のユニット種類 division.Extra5 = (UnitType) type; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // brigade_model if (keyword.Equals("brigade_model")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "brigade_model", lexer); continue; } // 付属旅団のモデル番号 division.BrigadeModel1 = (int) n; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // brigade_model1 if (keyword.Equals("brigade_model1")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "brigade_model1", lexer); continue; } // 付属旅団のモデル番号 division.BrigadeModel1 = (int) n; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // brigade_model2 if (keyword.Equals("brigade_model2")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "brigade_model2", lexer); continue; } // 付属旅団のモデル番号 division.BrigadeModel2 = (int) n; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // brigade_model3 if (keyword.Equals("brigade_model3")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "brigade_model3", lexer); continue; } // 付属旅団のモデル番号 division.BrigadeModel3 = (int) n; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // brigade_model4 if (keyword.Equals("brigade_model4")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "brigade_model4", lexer); continue; } // 付属旅団のモデル番号 division.BrigadeModel4 = (int) n; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // brigade_model5 if (keyword.Equals("brigade_model5")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "brigade_model5", lexer); continue; } // 付属旅団のモデル番号 division.BrigadeModel5 = (int) n; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); if (lexer.LineNo != lastLineNo) { // 現在行が最終解釈行と異なる場合、閉じ括弧が不足しているものと見なす lexer.ReserveToken(token); break; } lexer.SkipLine(); } return division; }
/// <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 Division ParseDivision(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; } Division division = new Division(); 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の組 division.Id = id; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // name if (keyword.Equals("name")) { string s = ParseString(lexer); if (s == null) { Log.InvalidClause(LogCategory, "name", lexer); continue; } // 師団名 division.Name = s; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // type if (keyword.Equals("type")) { UnitType? type = ParseDivisionType(lexer); if (type == null) { Log.InvalidClause(LogCategory, "type", lexer); continue; } // ユニット種類 division.Type = (UnitType) type; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // model if (keyword.Equals("model")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "model", lexer); continue; } // モデル番号 division.Model = (int) n; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // nuke if (keyword.Equals("nuke")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "nuke", lexer); continue; } // 核兵器搭載 division.Nuke = (bool) b; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // extra if (keyword.Equals("extra")) { UnitType? type = ParseBrigadeType(lexer); if (type == null) { Log.InvalidClause(LogCategory, "extra", lexer); continue; } // 付属旅団のユニット種類 division.Extra1 = (UnitType) type; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // extra1 if (keyword.Equals("extra1")) { UnitType? type = ParseBrigadeType(lexer); if (type == null) { Log.InvalidClause(LogCategory, "extra1", lexer); continue; } // 付属旅団のユニット種類 division.Extra1 = (UnitType) type; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // extra2 if (keyword.Equals("extra2")) { UnitType? type = ParseBrigadeType(lexer); if (type == null) { Log.InvalidClause(LogCategory, "extra2", lexer); continue; } // 付属旅団のユニット種類 division.Extra2 = (UnitType) type; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // extra3 if (keyword.Equals("extra3")) { UnitType? type = ParseBrigadeType(lexer); if (type == null) { Log.InvalidClause(LogCategory, "extra3", lexer); continue; } // 付属旅団のユニット種類 division.Extra3 = (UnitType) type; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // extra4 if (keyword.Equals("extra4")) { UnitType? type = ParseBrigadeType(lexer); if (type == null) { Log.InvalidClause(LogCategory, "extra4", lexer); continue; } // 付属旅団のユニット種類 division.Extra4 = (UnitType) type; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // extra5 if (keyword.Equals("extra5")) { UnitType? type = ParseBrigadeType(lexer); if (type == null) { Log.InvalidClause(LogCategory, "extra5", lexer); continue; } // 付属旅団のユニット種類 division.Extra5 = (UnitType) type; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // brigade_model if (keyword.Equals("brigade_model")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "brigade_model", lexer); continue; } // 付属旅団のモデル番号 division.BrigadeModel1 = (int) n; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // brigade_model1 if (keyword.Equals("brigade_model1")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "brigade_model1", lexer); continue; } // 付属旅団のモデル番号 division.BrigadeModel1 = (int) n; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // brigade_model2 if (keyword.Equals("brigade_model2")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "brigade_model2", lexer); continue; } // 付属旅団のモデル番号 division.BrigadeModel2 = (int) n; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // brigade_model3 if (keyword.Equals("brigade_model3")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "brigade_model3", lexer); continue; } // 付属旅団のモデル番号 division.BrigadeModel3 = (int) n; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // brigade_model4 if (keyword.Equals("brigade_model4")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "brigade_model4", lexer); continue; } // 付属旅団のモデル番号 division.BrigadeModel4 = (int) n; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // brigade_model5 if (keyword.Equals("brigade_model5")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "brigade_model5", lexer); continue; } // 付属旅団のモデル番号 division.BrigadeModel5 = (int) n; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // max_strength if (keyword.Equals("max_strength")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "max_strength", lexer); continue; } // 最大戦力 division.MaxStrength = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // strength if (keyword.Equals("strength")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "strength", lexer); continue; } // 戦力 division.Strength = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // defaultorganisation if (keyword.Equals("defaultorganisation")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "defaultorganisation", lexer); continue; } // 最大組織率 division.MaxOrganisation = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // organisation if (keyword.Equals("organisation")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "organisation", lexer); continue; } // 組織率 division.Organisation = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // morale if (keyword.Equals("morale")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "morale", lexer); continue; } // 士気 division.Morale = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // experience if (keyword.Equals("experience")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "experience", lexer); continue; } // 経験値 division.Experience = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // div_upgr_progress if (keyword.Equals("div_upgr_progress")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "div_upgr_progress", lexer); continue; } // 改良進捗率 division.UpgradeProgress = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // redep_target if (keyword.Equals("redep_target")) { int? n = ParseInt(lexer); if (!n.HasValue) { Log.InvalidClause(LogCategory, "redep_target", lexer); continue; } // 再配置先プロヴィンス division.RedeployTarget = (int) n; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // redep_unit_name if (keyword.Equals("redep_unit_name")) { string s = ParseString(lexer); if (s == null) { Log.InvalidClause(LogCategory, "redep_unit_name", lexer); continue; } // 再配置先ユニット名 division.RedeployUnitName = s; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // redep_unit_id if (keyword.Equals("redep_unit_id")) { TypeId id = ParseTypeId(lexer); if (id == null) { Log.InvalidSection(LogCategory, "redep_unit_id", lexer); continue; } // 再配置先ユニットID division.RedeployUnitId = id; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // offensive if (keyword.Equals("offensive")) { GameDate date = ParseDate(lexer); if (date == null) { Log.InvalidSection(LogCategory, "offensive", lexer); continue; } // 攻勢開始日時 division.Offensive = date; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // supplies if (keyword.Equals("supplies")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "supplies", lexer); continue; } // 物資 division.Supplies = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // oil if (keyword.Equals("oil")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "oil", lexer); continue; } // 燃料 division.Fuel = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // max_supply_stock if (keyword.Equals("max_supply_stock")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "max_supply_stock", lexer); continue; } // 最大物資 division.MaxSupplies = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // max_oil_stock if (keyword.Equals("max_oil_stock")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "max_oil_stock", lexer); continue; } // 最大燃料 division.MaxFuel = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // supplyconsumption if (keyword.Equals("supplyconsumption")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "supplyconsumption", lexer); continue; } // 物資消費量 division.SupplyConsumption = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // fuelconsumption if (keyword.Equals("fuelconsumption")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "fuelconsumption", lexer); continue; } // 燃料消費量 division.FuelConsumption = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // maxspeed if (keyword.Equals("maxspeed")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "maxspeed", lexer); continue; } // 最大速度 division.MaxSpeed = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // speed_cap_art if (keyword.Equals("speed_cap_art")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "speed_cap_art", lexer); continue; } // 砲兵速度キャップ division.SpeedCapArt = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // speed_cap_eng if (keyword.Equals("speed_cap_eng")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "speed_cap_eng", lexer); continue; } // 工兵速度キャップ division.SpeedCapEng = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // speed_cap_aa if (keyword.Equals("speed_cap_aa")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "speed_cap_aa", lexer); continue; } // 対空速度キャップ division.SpeedCapAa = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // speed_cap_at if (keyword.Equals("speed_cap_at")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "speed_cap_at", lexer); continue; } // 対戦車速度キャップ division.SpeedCapAt = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // transportweight if (keyword.Equals("transportweight")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "transportweight", lexer); continue; } // 輸送負荷 division.TransportWeight = (double) d; continue; } // transportcapability if (keyword.Equals("transportcapability")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "transportcapability", lexer); continue; } // 輸送能力 division.TransportCapability = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // defensiveness if (keyword.Equals("defensiveness")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "defensiveness", lexer); continue; } // 防御力 division.Defensiveness = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // toughness if (keyword.Equals("toughness")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "toughness", lexer); continue; } // 耐久力 division.Toughness = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // softness if (keyword.Equals("softness")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "softness", lexer); continue; } // 脆弱性 division.Softness = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // suppression if (keyword.Equals("suppression")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "suppression", lexer); continue; } // 制圧力 division.Suppression = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // seadefence if (keyword.Equals("seadefence")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "seadefence", lexer); continue; } // 対艦/対潜防御力 division.SeaDefense = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // surfacedefence if (keyword.Equals("surfacedefence")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "surfacedefence", lexer); continue; } // 対地防御力 division.SurfaceDefence = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // airdefence if (keyword.Equals("airdefence")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "airdefence", lexer); continue; } // 対空防御力 division.AirDefence = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // softattack if (keyword.Equals("softattack")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "softattack", lexer); continue; } // 対人攻撃力 division.SoftAttack = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // hardattack if (keyword.Equals("hardattack")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "hardattack", lexer); continue; } // 対甲攻撃力 division.HardAttack = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // seaattack if (keyword.Equals("seaattack")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "seaattack", lexer); continue; } // 対艦攻撃力(海軍) division.SeaAttack = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // subattack if (keyword.Equals("subattack")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "subattack", lexer); continue; } // 対潜攻撃力 division.SubAttack = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // convoyattack if (keyword.Equals("convoyattack")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "convoyattack", lexer); continue; } // 通商破壊力 division.ConvoyAttack = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // shorebombardment if (keyword.Equals("shorebombardment")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "shorebombardment", lexer); continue; } // 沿岸砲撃能力 division.ShoreBombardment = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // airattack if (keyword.Equals("airattack")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "airattack", lexer); continue; } // 対空攻撃力 division.AirAttack = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // strategicattack if (keyword.Equals("strategicattack")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "strategicattack", lexer); continue; } // 戦略爆撃攻撃力 division.StrategicAttack = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // navalattack if (keyword.Equals("navalattack")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "navalattack", lexer); continue; } // 空対艦攻撃力 division.NavalAttack = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // artillery_bombardment if (keyword.Equals("artillery_bombardment")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "artillery_bombardment", lexer); continue; } // 砲撃能力 division.ArtilleryBombardment = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // surfacedetectioncapability if (keyword.Equals("surfacedetectioncapability")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "surfacedetectioncapability", lexer); continue; } // 対艦索敵能力 division.SurfaceDetection = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // airdetectioncapability if (keyword.Equals("airdetectioncapability")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "airdetectioncapability", lexer); continue; } // 対空索敵能力 division.AirDetection = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // subdetectioncapability if (keyword.Equals("subdetectioncapability")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "subdetectioncapability", lexer); continue; } // 対潜索敵能力 division.SubDetection = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // visibility if (keyword.Equals("visibility")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "visibility", lexer); continue; } // 可視性 division.Visibility = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // range if (keyword.Equals("range")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "range", lexer); continue; } // 航続距離 division.Range = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // distance if (keyword.Equals("distance")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "distance", lexer); continue; } // 射程距離 division.Distance = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // travelled if (keyword.Equals("travelled")) { double? d = ParseDouble(lexer); if (!d.HasValue) { Log.InvalidClause(LogCategory, "travelled", lexer); continue; } // 移動距離 division.Travelled = (double) d; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // locked if (keyword.Equals("locked")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "dormant", lexer); continue; } // 移動不可 division.Locked = (bool) b; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // dormant if (keyword.Equals("dormant")) { bool? b = ParseBool(lexer); if (!b.HasValue) { Log.InvalidClause(LogCategory, "dormant", lexer); continue; } // 休止状態 division.Dormant = (bool) b; // 最終解釈行を覚えておく lastLineNo = lexer.LineNo; continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); if (lexer.LineNo != lastLineNo) { // 現在行が最終解釈行と異なる場合、閉じ括弧が不足しているものと見なす lexer.ReserveToken(token); break; } lexer.SkipLine(); } return division; }
/// <summary> /// 外交設定を構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>外交設定</returns> private static IEnumerable<Relation> ParseDiplomacy(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.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); return null; } List<Relation> list = new List<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(); // relation if (keyword.Equals("relation")) { Relation relation = ParseRelation(lexer); if (relation == null) { Log.InvalidSection(LogCategory, "relation", lexer); continue; } // 外交関係設定 list.Add(relation); continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.ReserveToken(token); break; } return list; }
/// <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> /// 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; }
/// <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); }