/// <summary> /// 字句解析・構文解析用。ホワイトスペースの他、コメントも飛ばす。 /// </summary> public static int SkipWhiteSpace(StringStream st) { int count = 0; while (true) { switch (st.Current) { case ' ': case '\t': count++; st.ShiftNext(); continue; case ' ': if (!Config.SystemAllowFullSpace) { return(count); } goto case ' '; case ';': if (st.CurrentEqualTo(";#;") && Program.DebugMode) { st.Jump(3); continue; } else if (st.CurrentEqualTo(";!;")) { st.Jump(3); continue; } st.Seek(0, System.IO.SeekOrigin.End); return(count); } return(count); } }
/// <summary> /// 解析できるものは関数宣言や式のみ。FORM文字列や普通の文字列を送ってはいけない /// return時にはendWithの文字がCurrentになっているはず。終端の適切さの検証は呼び出し元が行う。 /// </summary> /// <returns></returns> public static WordCollection Analyse(StringStream st, LexEndWith endWith, LexAnalyzeFlag flag) { WordCollection ret = new WordCollection(); int nestBracketS = 0; //int nestBracketM = 0; int nestBracketL = 0; while (true) { switch (st.Current) { case '\n': case '\0': goto end; case ' ': case '\t': st.ShiftNext(); continue; case ' ': if (!Config.SystemAllowFullSpace) { throw new CodeEE("字句解析中に予期しない全角スペースを発見しました(この警告はシステムオプション「" + Config.GetConfigName(ConfigCode.SystemAllowFullSpace) + "」により無視できます)"); } st.ShiftNext(); continue; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': ret.Add(new LiteralIntegerWord(ReadInt64(st, false))); break; case '>': if (endWith == LexEndWith.GreaterThan) { goto end; } goto case '+'; case '+': case '-': case '*': case '/': case '%': case '=': case '!': case '<': case '|': case '&': case '^': case '~': case '?': case '#': if ((nestBracketS == 0) && (nestBracketL == 0)) { if (endWith == LexEndWith.Operator) { goto end; //代入演算子のはずである。呼び出し元がチェックするはず } else if ((endWith == LexEndWith.Percent) && (st.Current == '%')) { goto end; } else if ((endWith == LexEndWith.Question) && (st.Current == '?')) { goto end; } } ret.Add(new OperatorWord(ReadOperator(st, (flag & LexAnalyzeFlag.AllowAssignment) == LexAnalyzeFlag.AllowAssignment))); break; case ')': ret.Add(new SymbolWord(')')); nestBracketS--; st.ShiftNext(); continue; case ']': ret.Add(new SymbolWord(']')); nestBracketL--; st.ShiftNext(); continue; case '(': ret.Add(new SymbolWord('(')); nestBracketS++; st.ShiftNext(); continue; case '[': if (st.Next == '[') { //throw new CodeEE("字句解析中に予期しない文字'[['を発見しました"); ////1808alpha006 rename処理変更 //1808beta009 ここだけ戻す //現在の処理だとここに来た時点でrename失敗確定だが警告内容を元に戻すため if (ParserMediator.RenameDic == null) { throw new CodeEE("字句解析中に予期しない文字\"[[\"を発見しました"); } int start = st.CurrentPosition; int find = st.Find("]]"); if (find <= 2) { if (find == 2) { throw new CodeEE("空の[[]]です"); } else { throw new CodeEE("対応する\"]]\"のない\"[[\"です"); } } string key = st.Substring(start, find + 2); //1810 ここまでで置換できなかったものは強制エラーにする //行連結前に置換不能で行連結より置換することができるようになったものまで置換されていたため throw new CodeEE("字句解析中に置換(rename)できない符号" + key + "を発見しました"); //string value = null; //if (!ParserMediator.RenameDic.TryGetValue(key, out value)) // throw new CodeEE("字句解析中に置換(rename)できない符号" + key + "を発見しました"); //st.Replace(start, find + 2, value); //continue;//その場から再度解析スタート } ret.Add(new SymbolWord('[')); nestBracketL++; st.ShiftNext(); continue; case ':': ret.Add(new SymbolWord(':')); st.ShiftNext(); continue; case ',': if ((endWith == LexEndWith.Comma) && (nestBracketS == 0)) // && (nestBracketL == 0)) { goto end; } ret.Add(new SymbolWord(',')); st.ShiftNext(); continue; //case '}': ret.Add(new SymbolWT('}')); nestBracketM--; continue; //case '{': ret.Add(new SymbolWT('{')); nestBracketM++; continue; case '\'': if ((flag & LexAnalyzeFlag.AllowSingleQuotationStr) == LexAnalyzeFlag.AllowSingleQuotationStr) { st.ShiftNext(); ret.Add(new LiteralStringWord(ReadString(st, StrEndWith.SingleQuotation))); if (st.Current != '\'') { throw new CodeEE("\'が閉じられていません"); } st.ShiftNext(); break; } if ((flag & LexAnalyzeFlag.AnalyzePrintV) != LexAnalyzeFlag.AnalyzePrintV) { //AssignmentStr用特殊処理 代入文の代入演算子を探索中で'=の場合のみ許可 if ((endWith == LexEndWith.Operator) && (nestBracketS == 0) && (nestBracketL == 0) && st.Next == '=') { goto end; } throw new CodeEE("字句解析中に予期しない文字'" + st.Current + "'を発見しました"); } st.ShiftNext(); ret.Add(new LiteralStringWord(ReadString(st, StrEndWith.Comma))); if (st.Current == ',') { goto case ','; //続きがあるなら,の処理へ。それ以外は行終端のはず } goto end; case '}': if (endWith == LexEndWith.RightCurlyBrace) { goto end; } throw new CodeEE("字句解析中に予期しない文字'" + st.Current + "'を発見しました"); case '\"': st.ShiftNext(); ret.Add(new LiteralStringWord(ReadString(st, StrEndWith.DoubleQuotation))); if (st.Current != '\"') { throw new CodeEE("\"が閉じられていません"); } st.ShiftNext(); break; case '@': if (st.Next != '\"') { ret.Add(new SymbolWord('@')); st.ShiftNext(); continue; } st.ShiftNext(); st.ShiftNext(); ret.Add(AnalyseFormattedString(st, FormStrEndWith.DoubleQuotation, false)); if (st.Current != '\"') { throw new CodeEE("\"が閉じられていません"); } st.ShiftNext(); break; case '.': ret.Add(new SymbolWord('.')); st.ShiftNext(); continue; case '\\': if (st.Next != '@') { throw new CodeEE("字句解析中に予期しない文字'" + st.Current + "'を発見しました"); } { st.Jump(2); ret.Add(new StrFormWord(new string[] { "", "" }, new SubWord[] { AnalyseYenAt(st) })); } break; case '{': case '$': throw new CodeEE("字句解析中に予期しない文字'" + st.Current + "'を発見しました"); case ';': //1807 行中コメント if (st.CurrentEqualTo(";#;") && Program.DebugMode) { st.Jump(3); break; } else if (st.CurrentEqualTo(";!;")) { st.Jump(3); break; } st.Seek(0, System.IO.SeekOrigin.End); goto end; default: { ret.Add(new IdentifierWord(ReadSingleIdentifier(st))); break; } } } end: if ((nestBracketS != 0) || (nestBracketL != 0)) { if (nestBracketS < 0) { throw new CodeEE("字句解析中に対応する'('のない')'を発見しました"); } else if (nestBracketS > 0) { throw new CodeEE("字句解析中に対応する')'のない'('を発見しました"); } if (nestBracketL < 0) { throw new CodeEE("字句解析中に対応する'['のない']'を発見しました"); } else if (nestBracketL > 0) { throw new CodeEE("字句解析中に対応する']'のない'['を発見しました"); } } if (UseMacro) { return(expandMacro(ret)); } return(ret); }
/// <summary> /// @"などの直後からの開始 /// return時にはendWithの文字がCurrentになっているはず。終端の適切さの検証は呼び出し元が行う。 /// </summary> /// <returns></returns> public static StrFormWord AnalyseFormattedString(StringStream st, FormStrEndWith endWith, bool trim) { List <string> strs = new List <string>(); List <SubWord> SWTs = new List <SubWord>(); StringBuilder buffer = new StringBuilder(100); while (true) { char cur = st.Current; switch (cur) { case '\n': case '\0': goto end; case '\"': if (endWith == FormStrEndWith.DoubleQuotation) { goto end; } buffer.Append(cur); break; case '#': if (endWith == FormStrEndWith.Sharp) { goto end; } buffer.Append(cur); break; case ',': if ((endWith == FormStrEndWith.Comma) || (endWith == FormStrEndWith.LeftParenthesis_Bracket_Comma_Semicolon)) { goto end; } buffer.Append(cur); break; case '(': case '[': case ';': if (endWith == FormStrEndWith.LeftParenthesis_Bracket_Comma_Semicolon) { goto end; } buffer.Append(cur); break; case '%': strs.Add(buffer.ToString()); buffer.Remove(0, buffer.Length); st.ShiftNext(); SWTs.Add(new PercentSubWord(Analyse(st, LexEndWith.Percent, LexAnalyzeFlag.None))); if (st.Current != '%') { throw new CodeEE("\'%\'が使われましたが対応する\'%\'が見つかりません"); } break; case '{': strs.Add(buffer.ToString()); buffer.Remove(0, buffer.Length); st.ShiftNext(); SWTs.Add(new CurlyBraceSubWord(Analyse(st, LexEndWith.RightCurlyBrace, LexAnalyzeFlag.None))); if (st.Current != '}') { throw new CodeEE("\'{\'が使われましたが対応する\'}\'が見つかりません"); } break; case '*': case '+': case '=': case '/': case '$': if (!Config.SystemIgnoreTripleSymbol && st.TripleSymbol()) { strs.Add(buffer.ToString()); buffer.Remove(0, buffer.Length); st.Jump(3); SWTs.Add(new TripleSymbolSubWord(cur)); continue; } else { buffer.Append(cur); } break; case '\\': //エスケープ文字の使用 st.ShiftNext(); cur = st.Current; switch (cur) { case '\0': throw new CodeEE("エスケープ文字\\の後に文字がありません"); case '\n': break; case 's': buffer.Append(' '); break; case 'S': buffer.Append(' '); break; case 't': buffer.Append('\t'); break; case 'n': buffer.Append('\n'); break; case '@': //\@~~?~~#~~\@ { if ((endWith == FormStrEndWith.YenAt) || (endWith == FormStrEndWith.Sharp)) { goto end; } strs.Add(buffer.ToString()); buffer.Remove(0, buffer.Length); st.ShiftNext(); SWTs.Add(AnalyseYenAt(st)); continue; } default: buffer.Append(cur); st.ShiftNext(); continue; } break; default: buffer.Append(cur); break; } st.ShiftNext(); } end: strs.Add(buffer.ToString()); string[] retStr = new string[strs.Count]; SubWord[] retSWTs = new SubWord[SWTs.Count]; strs.CopyTo(retStr); SWTs.CopyTo(retSWTs); if (trim && retStr.Length > 0) { retStr[0] = retStr[0].TrimStart(new char[] { ' ', '\t' }); retStr[retStr.Length - 1] = retStr[retStr.Length - 1].TrimEnd(new char[] { ' ', '\t' }); } return(new StrFormWord(retStr, retSWTs)); }
public PRINT_DATA_Instruction(string name) { //PRINTDATA(|K)(|D)(|L|W) flag = EXTENDED | IS_PRINT | PARTIAL; ArgBuilder = ArgumentParser.GetArgumentBuilder(FunctionArgType.VAR_INT); StringStream st = new StringStream(name); st.Jump(9);//PRINTDATA if (st.CurrentEqualTo("K")) { flag |= ISPRINTKFUNC | EXTENDED; st.Jump(1); } if (st.CurrentEqualTo("D")) { flag |= ISPRINTDFUNC | EXTENDED; st.Jump(1); } if (st.CurrentEqualTo("L")) { flag |= PRINT_NEWLINE; flag |= METHOD_SAFE; st.Jump(1); } else if (st.CurrentEqualTo("W")) { flag |= PRINT_NEWLINE | PRINT_WAITINPUT; st.Jump(1); } else { flag |= METHOD_SAFE; } if ((ArgBuilder == null) || (!st.EOS)) throw new ExeEE("PRINTDATA異常"); }
public PRINT_Instruction(string name) { //PRINT(|V|S|FORM|FORMS)(|K)(|D)(|L|W) コレと //PRINTSINGLE(|V|S|FORM|FORMS)(|K)(|D) コレと //PRINT(|FORM)(C|LC)(|K)(|D) コレ //PRINTDATA(|K)(|D)(|L|W) ←は別クラス flag = IS_PRINT; StringStream st = new StringStream(name); st.Jump(5);//PRINT if (st.CurrentEqualTo("SINGLE")) { flag |= PRINT_SINGLE | EXTENDED; st.Jump(6); } if (st.CurrentEqualTo("V")) { ArgBuilder = ArgumentParser.GetArgumentBuilder(FunctionArgType.SP_PRINTV); isPrintV = true; st.Jump(1); } else if (st.CurrentEqualTo("S")) { ArgBuilder = ArgumentParser.GetArgumentBuilder(FunctionArgType.STR_EXPRESSION); st.Jump(1); } else if (st.CurrentEqualTo("FORMS")) { ArgBuilder = ArgumentParser.GetArgumentBuilder(FunctionArgType.STR_EXPRESSION); isForms = true; st.Jump(5); } else if (st.CurrentEqualTo("FORM")) { ArgBuilder = ArgumentParser.GetArgumentBuilder(FunctionArgType.FORM_STR_NULLABLE); st.Jump(4); } else { ArgBuilder = ArgumentParser.GetArgumentBuilder(FunctionArgType.STR_NULLABLE); } if (st.CurrentEqualTo("LC")) { flag |= EXTENDED; isLC = true; st.Jump(2); } else if (st.CurrentEqualTo("C")) { if (name == "PRINTFORMC") flag |= EXTENDED; isC = true; st.Jump(1); } if (st.CurrentEqualTo("K")) { flag |= ISPRINTKFUNC | EXTENDED; st.Jump(1); } if (st.CurrentEqualTo("D")) { flag |= ISPRINTDFUNC | EXTENDED; st.Jump(1); } if (st.CurrentEqualTo("L")) { flag |= PRINT_NEWLINE; flag |= METHOD_SAFE; st.Jump(1); } else if (st.CurrentEqualTo("W")) { flag |= PRINT_NEWLINE | PRINT_WAITINPUT; st.Jump(1); } else { flag |= METHOD_SAFE; } if ((ArgBuilder == null) || (!st.EOS)) throw new ExeEE("PRINT異常"); }
public PICTURE_Instruction(string name) { StringStream st = new StringStream(name); st.Jump(7); isOpen = false; isClose = false; if (st.CurrentEqualTo("OPEN")) { isOpen = true; st.Jump(4); } if (st.CurrentEqualTo("CLOSE")) { isClose = true; st.Jump(5); } ArgBuilder = ArgumentParser.GetArgumentBuilder(FunctionArgType.STR_NULLABLE); flag |= METHOD_SAFE; if ((ArgBuilder == null) || (!st.EOS)) throw new ExeEE("Picture異常"); }
public MUSIC_Instruction(string name) { StringStream st = new StringStream(name); st.Jump(5); isSet = false; isClose = false; isPlay = false; isStop = false; isLoop = false; isSe = false; isXwb = false; if (st.CurrentEqualTo("X")) { isXwb = true; isSet = true; st.Jump(1); } if (st.CurrentEqualTo("SE")) { isSe = true; isPlay = true; st.Jump(2); } if (st.CurrentEqualTo("PLAY")) { isSet = true; isStop = false; isPlay = true; st.Jump(4); } if (st.CurrentEqualTo("STOP")) { isPlay = false; isClose = true; isStop = true; st.Jump(4); } if (st.CurrentEqualTo("LOOP")) { isPlay = true; isStop = true; isLoop = true; st.Jump(4); } ArgBuilder = ArgumentParser.GetArgumentBuilder(FunctionArgType.STR_NULLABLE); flag |= METHOD_SAFE; if ((ArgBuilder == null) || (!st.EOS)) throw new ExeEE("SOUND異常"); }
/// <summary> /// 字句解析・構文解析用。ホワイトスペースの他、コメントも飛ばす。 /// </summary> public static int SkipWhiteSpace(StringStream st) { int count = 0; while (true) { switch (st.Current) { case ' ': case '\t': count++; st.ShiftNext(); continue; case ' ': if (!Config.SystemAllowFullSpace) return count; //throw new CodeEE("予期しない全角スペースを発見しました"); goto case ' '; case ';': if (st.CurrentEqualTo(";#;") && Program.DebugMode) { st.Jump(3); continue; } else if (st.CurrentEqualTo(";!;")) { st.Jump(3); continue; } st.Seek(0, System.IO.SeekOrigin.End); return count; } return count; } }
/// <summary> /// 解析できるものは関数宣言や式のみ。FORM文字列や普通の文字列を送ってはいけない /// return時にはendWithの文字がCurrentになっているはず。終端の適切さの検証は呼び出し元が行う。 /// </summary> /// <returns></returns> public static WordCollection Analyse(StringStream st, LexEndWith endWith, bool isPrintV, bool allowAssignment) { WordCollection ret = new WordCollection(); int nestBracketS = 0; //int nestBracketM = 0; int nestBracketL = 0; while (true) { switch (st.Current) { case '\n': case '\0': goto end; case ' ': case '\t': st.ShiftNext(); continue; case ' ': if (!Config.SystemAllowFullSpace) throw new CodeEE("字句解析中に予期しない全角スペースを発見しました"); st.ShiftNext(); continue; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': ret.Add(new LiteralIntegerWord(ReadInt64(st, false))); break; case '+': case '-': case '*': case '/': case '%': case '=': case '!': case '<': case '>': case '|': case '&': case '^': case '~': case '?': case '#': if ((nestBracketS == 0) && (nestBracketL == 0)) { if (endWith == LexEndWith.Operator) goto end;//代入演算子のはずである。呼び出し元がチェックするはず else if ((endWith == LexEndWith.Percent) && (st.Current == '%')) goto end; else if ((endWith == LexEndWith.Question) && (st.Current == '?')) goto end; } ret.Add(new OperatorWord(ReadOperator(st, allowAssignment))); break; case ')': ret.Add(new SymbolWord(')')); nestBracketS--; st.ShiftNext(); continue; case ']': ret.Add(new SymbolWord(']')); nestBracketL--; st.ShiftNext(); continue; case '(': ret.Add(new SymbolWord('(')); nestBracketS++; st.ShiftNext(); continue; case '[': if (st.Next == '[') { //throw new CodeEE("字句解析中に予期しない文字'[['を発見しました"); ////1808alpha006 rename処理変更 //1808beta009 ここだけ戻す //現在の処理だとここに来た時点でrename失敗確定だが警告内容を元に戻すため if (ParserMediator.RenameDic == null) throw new CodeEE("字句解析中に予期しない文字\"[[\"を発見しました"); int start = st.CurrentPosition; int find = st.Find("]]"); if (find <= 2) { if (find == 2) throw new CodeEE("空の[[]]です"); else throw new CodeEE("対応する\"]]\"のない\"[[\"です"); } string key = st.Substring(start, find + 2); string value = null; if (!ParserMediator.RenameDic.TryGetValue(key, out value)) throw new CodeEE("字句解析中に置換(rename)できない符号" + key + "を発見しました"); st.Replace(start, find + 2, value); continue;//その場から再度解析スタート } ret.Add(new SymbolWord('[')); nestBracketL++; st.ShiftNext(); continue; case ':': ret.Add(new SymbolWord(':')); st.ShiftNext(); continue; case ',': if ((endWith == LexEndWith.Comma) && (nestBracketS == 0))// && (nestBracketL == 0)) goto end; ret.Add(new SymbolWord(',')); st.ShiftNext(); continue; //case '}': ret.Add(new SymbolWT('}')); nestBracketM--; continue; //case '{': ret.Add(new SymbolWT('{')); nestBracketM++; continue; case '\'': if (!isPrintV) throw new CodeEE("字句解析中に予期しない文字'" + st.Current + "'を発見しました"); st.ShiftNext(); ret.Add(new LiteralStringWord(ReadString(st, StrEndWith.Comma))); if (st.Current == ',') goto case ',';//続きがあるなら,の処理へ。それ以外は行終端のはず goto end; case '}': if (endWith == LexEndWith.RightCurlyBrace) goto end; throw new CodeEE("字句解析中に予期しない文字'" + st.Current + "'を発見しました"); case '\"': st.ShiftNext(); ret.Add(new LiteralStringWord(ReadString(st, StrEndWith.DoubleQuotation))); if (st.Current != '\"') throw new CodeEE("\"が閉じられていません"); st.ShiftNext(); break; case '@': if (st.Next != '\"') { ret.Add(new SymbolWord('@')); st.ShiftNext(); continue; } st.ShiftNext(); st.ShiftNext(); ret.Add(AnalyseFormattedString(st, FormStrEndWith.DoubleQuotation, false)); if (st.Current != '\"') throw new CodeEE("\"が閉じられていません"); st.ShiftNext(); break; case '\\': if (st.Next != '@') throw new CodeEE("字句解析中に予期しない文字'" + st.Current + "'を発見しました"); { st.Jump(2); ret.Add(new StrFormWord(new string[] { "", "" }, new SubWord[] { AnalyseYenAt(st) })); } break; case '{': case '$': case '.': throw new CodeEE("字句解析中に予期しない文字'" + st.Current + "'を発見しました"); case ';'://1807 行中コメント if (st.CurrentEqualTo(";#;") && Program.DebugMode) { st.Jump(3); break; } else if (st.CurrentEqualTo(";!;")) { st.Jump(3); break; } st.Seek(0, System.IO.SeekOrigin.End); goto end; default: { ret.Add(new IdentifierWord(ReadSingleIdentifier(st))); break; } } } end: if ((nestBracketS != 0) || (nestBracketL != 0)) { if (nestBracketS < 0) throw new CodeEE("字句解析中に対応する'('のない')'を発見しました"); else if (nestBracketS > 0) throw new CodeEE("字句解析中に対応する')'のない'('を発見しました"); if (nestBracketL < 0) throw new CodeEE("字句解析中に対応する'['のない']'を発見しました"); else if (nestBracketL > 0) throw new CodeEE("字句解析中に対応する']'のない'['を発見しました"); } if (UseMacro) return expandMacro(ret); return ret; }
/// <summary> /// @"などの直後からの開始 /// return時にはendWithの文字がCurrentになっているはず。終端の適切さの検証は呼び出し元が行う。 /// </summary> /// <returns></returns> public static StrFormWord AnalyseFormattedString(StringStream st, FormStrEndWith endWith, bool trim) { List<string> strs = new List<string>(); List<SubWord> SWTs = new List<SubWord>(); StringBuilder buffer = new StringBuilder(100); while (true) { char cur = st.Current; switch (cur) { case '\n': case '\0': goto end; case '\"': if (endWith == FormStrEndWith.DoubleQuotation) goto end; buffer.Append(cur); break; case '#': if (endWith == FormStrEndWith.Sharp) goto end; buffer.Append(cur); break; case ',': if ((endWith == FormStrEndWith.Comma) || (endWith == FormStrEndWith.LeftParenthesis_Bracket_Comma_Semicolon)) goto end; buffer.Append(cur); break; case '(': case '[': case ';': if (endWith == FormStrEndWith.LeftParenthesis_Bracket_Comma_Semicolon) goto end; buffer.Append(cur); break; case '%': strs.Add(buffer.ToString()); buffer.Remove(0, buffer.Length); st.ShiftNext(); SWTs.Add(new PercentSubWord(Analyse(st, LexEndWith.Percent, false, false))); if (st.Current != '%') throw new CodeEE("\'%\'が使われましたが対応する\'%\'が見つかりません"); break; case '{': strs.Add(buffer.ToString()); buffer.Remove(0, buffer.Length); st.ShiftNext(); SWTs.Add(new CurlyBraceSubWord(Analyse(st, LexEndWith.RightCurlyBrace, false, false))); if (st.Current != '}') throw new CodeEE("\'{\'が使われましたが対応する\'}\'が見つかりません"); break; case '*': case '+': case '=': case '/': case '$': if (st.TripleSymbol()) { strs.Add(buffer.ToString()); buffer.Remove(0, buffer.Length); st.Jump(3); SWTs.Add(new TripleSymbolSubWord(cur)); continue; } else buffer.Append(cur); break; case '\\'://エスケープ文字の使用 st.ShiftNext(); cur = st.Current; switch (cur) { case '\0': throw new CodeEE("エスケープ文字\\の後に文字がありません"); case '\n': break; case 's': buffer.Append(' '); break; case 'S': buffer.Append(' '); break; case 't': buffer.Append('\t'); break; case 'n': buffer.Append('\n'); break; case '@'://\@~~?~~#~~\@ { if ((endWith == FormStrEndWith.YenAt) || (endWith == FormStrEndWith.Sharp)) goto end; strs.Add(buffer.ToString()); buffer.Remove(0, buffer.Length); st.ShiftNext(); SWTs.Add(AnalyseYenAt(st)); continue; } default: buffer.Append(cur); st.ShiftNext(); continue; } break; default: buffer.Append(cur); break; } st.ShiftNext(); } end: strs.Add(buffer.ToString()); string[] retStr = new string[strs.Count]; SubWord[] retSWTs = new SubWord[SWTs.Count]; strs.CopyTo(retStr); SWTs.CopyTo(retSWTs); if (trim && retStr.Length > 0) { retStr[0] = retStr[0].TrimStart(new char[] { ' ', '\t' }); retStr[retStr.Length - 1] = retStr[retStr.Length - 1].TrimEnd(new char[] { ' ', '\t' }); } return new StrFormWord(retStr, retSWTs); }