public string ToCSharpSource(ContextCompiler cc, ref bool last) { ICommand icmd = cc.cmdreg[this.command]; // last if (last) { cc.wreader.LetterReader.SetError("到達できない命令です。", this, this); return("/* Command '" + this.command + "' */\r\n"); } last = icmd.RequireLast; // require argument if (this.argument == "" && icmd.RequireArgument) { cc.wreader.LetterReader.SetError( "命令 '" + this.command + "' は引数を必要とします。() で括って引数を指定して下さい。", this, this); return("/* Command '" + this.command + "' */\r\n"); } try{ return(icmd.ToCSharpSource(cc, this.argument)); }catch (System.Exception e) { cc.wreader.LetterReader.SetError("命令コード生成中の例外: " + e.Message, this, this); return("/* Command '" + this.command + "' */\r\n"); } }
public string ToCSharpSource(ContextCompiler cc, string argument) { if (!cc.ContainsContext(argument)) { throw new System.ArgumentException("指定した名前 '" + argument + "' という Context は定義されていません。", "argument"); } return("this.ReadContext_" + argument + "();\r\n"); }
/// <summary> /// ContextStage を読み取ります。 /// </summary> /// <param name="p">読み取りを実行している ContextCompiler を指定します。</param> /// <param name="stage">読み取った stage を返します。</param> /// <returns>現在の Context 内の stage を全て読み終わってもう残りが無い時に false を返します。 /// それ以外の場合には stage を読み取って true を返します。</returns> public static bool Read(ContextCompiler p, out ContextStage stage) { stage = new ContextStage(); if (p.wreader.CurrentType == WordType.Invalid) { return(false); } stage.words = new System.Collections.Generic.List <ContextCondition>(); stage.cmds = new System.Collections.Generic.List <ContextCommand>(); // 分岐標 読み取り ContextCondition ctxword; while (p.wreader.CurrentType == WordType.Identifier) { if (!ContextCondition.Read(p, out ctxword)) { break; } stage.words.Add(ctxword); } if (p.wreader.CurrentType == WordType.Operator && p.wreader.CurrentWord == ":") { p.wreader.ReadNext(); } // 命令 読み取り ContextCommand ctxcmd; while (p.wreader.CurrentType == WordType.Identifier) { if (!ContextCommand.Read(p, out ctxcmd)) { break; } stage.cmds.Add(ctxcmd); } if (p.wreader.CurrentType == WordType.Operator && p.wreader.CurrentWord == ";") { p.wreader.ReadNext(); } // 結果判定 if (stage.cmds.Count == 0) { // 何も (命令も分岐標も) 読み取っていない時 if (stage.words.Count == 0) { return(false); } // 命令が一つもないのに分岐標がある時 p.wreader.LetterReader.SetError("対応する命令列が存在しません。", 0, null); stage.cmds.Add(new ContextCommand("ret", "")); } return(true); }
public static bool Read(ContextCompiler cc, out ContextCommand contextcmd) { contextcmd = new ContextCommand(); AbstractWordReader wreader = cc.wreader; start: if (wreader.CurrentType == WordType.Invalid) { return(false); } string word = wreader.CurrentWord; if (wreader.CurrentType != WordType.Identifier) { if (word == ";" || word == "}") { return(false); } throw new System.ApplicationException("Fatal: ここに制御は来る筈ない。ContextWordReader の実装が怪しい"); } // argument があればそれを読み取り。 wreader.LetterReader.CopyPosition(0, contextcmd); // 後でエラーが発生した時等の為。 wreader.LetterReader.CopyPosition(0, 1); // * wreader.LetterReader.StoreCurrentPos(2); // * if (wreader.ReadNext()) { if (wreader.CurrentType == WordType.Suffix) { contextcmd.argument = wreader.CurrentWord; wreader.LetterReader.StoreCurrentPos(2); // * wreader.ReadNext(); // 二重引数を跳ばし読み if (wreader.CurrentType == WordType.Suffix) { wreader.LetterReader.SetError("二重に引数を指定する事は出来ません。", 0, null); } while (wreader.CurrentType == WordType.Suffix) { wreader.ReadNext(); } } } // command が処理可能な物かどうかを確認。 if (!cc.cmdreg.ContainsKey(word)) { cc.wreader.LetterReader.SetError(word + " という種類の命令は定義されていません", 1, 2); // * goto start; // 読み直し } contextcmd.command = word; return(true); }
public string ToCSharpSource(ContextCompiler cc, string argument) { if (argument == "") { return("this.wreader.LetterReader.SetError(\"解析中の不明なエラー\",0,null);\r\n"); } else { return("this.wreader.LetterReader.SetError(\"エラー: " + argument.Replace(@"\", @"\\").Replace("\"", "\\\"") + "\",0,null);\r\n"); } }
public static bool Read(ContextCompiler p, out ContextCondition contextword) { contextword = null; string wordtype = ""; string word; if (p.wreader.CurrentType == WordType.Invalid) { return(false); } start: if (p.wreader.CurrentType != WordType.Identifier) { if (p.wreader.CurrentWord == ":" || p.wreader.CurrentWord == "}") { return(false); } throw new System.ApplicationException("Fatal: ここに制御は来る筈ない。ContextWordReader の実装が怪しい"); } // word 取得 word = p.wreader.CurrentWord; if (word[0] == '<' && word[word.Length - 1] == '>') { if (word != "<def>" && word != "<nul>") { // TODO: <> でユーザ定義の分岐標を指定できる様にする予定 p.wreader.LetterReader.SetError(word + " という種類の分岐先は定義されていません", 0, null); if (!p.wreader.ReadNext()) { return(false); } goto start; } } else if (word[0] == '[') { int i = word.IndexOf(']', 1); if (i > 0) { // type 指定 [] がある場合 wordtype = word.Substring(1, i - 1); word = word.Substring(i + 1); } } contextword = new ContextCondition(word, wordtype); p.wreader.LetterReader.CopyPosition(0, contextword); // 後で起こったエラーの際の参照 p.wreader.ReadNext(); return(true); }
public override string Translate(string inputText, string defaultNamespace, Microsoft.VisualStudio.Shell.Interop.IVsGeneratorProgress generateProgress) { ContextCompiler cc = new ContextCompiler(); cc.DefaultNamespace = defaultNamespace; cc.Parse(inputText); string r = cc.ToCSharpSource(); foreach (ContextCompiler.ErrorInfo err in cc.EnumErrors()) { generateProgress.GeneratorError(0, 0, err.message, (uint)err.line, (uint)err.column + 1); } return(r); }
public string ToCSharpSource(ContextCompiler cc, string argument) { const string ARG_NOTINTEGER = "jump 命令の引数には 0 以上の整数を指定して下さい。"; int x; try{ x = int.Parse(argument); if (x < 0) { throw new System.ArgumentException(ARG_NOTINTEGER, "argument"); } }catch (System.Exception e) { throw new System.ArgumentException(ARG_NOTINTEGER, "argument", e); } return("goto label_" + x.ToString() + ";\r\n"); }
public static bool Read(ContextCompiler cc, out UserCommand usercmd) { usercmd = new UserCommand(); AbstractWordReader wreader = cc.wreader; // command while (wreader.CurrentType != WordType.Identifier || wreader.CurrentWord != "command") { wreader.LetterReader.SetError("command の開始には keyword 'command' が必要です。", 0, null); if (!wreader.ReadNext()) { return(false); } } wreader.ReadNext(); // CommandName while (wreader.CurrentType != WordType.Identifier) { wreader.LetterReader.SetError("keyword 'context' の後には識別子が必要です。", 0, null); if (!wreader.ReadNext()) { return(false); } } usercmd.name = wreader.CurrentWord; wreader.ReadNext(); // {} while (wreader.CurrentType != WordType.Literal) { wreader.LetterReader.SetError("command 宣言の後には command の中身が必要です。中身は { で始めて下さい。", 0, null); if (!wreader.ReadNext()) { return(false); } } usercmd.content = FormatSource(wreader.CurrentWord); wreader.ReadNext(); return(true); }
public string ToCSharpSource(ContextCompiler cc) { const string METHOD_SIGNATURE = @" [System.Runtime.CompilerServices.CompilerGenerated] private void ReadContext_{0}(){{ string word;" ; const string LABEL_TEMPLATE = @" #pragma warning disable 164 label_{0}: #pragma warning restore 164 word=this.wreader.CurrentWord; " ; //----------------------------------- System.Text.StringBuilder builder = new System.Text.StringBuilder(); int stagenum = 0; bool label = true; builder.AppendFormat(METHOD_SIGNATURE, this.name); foreach (ContextStage stage in this.data) { // label if (label) { builder.AppendFormat(LABEL_TEMPLATE, stagenum++); } else { builder.Append("else "); } // content string src = stage.ToCSharpSource(cc); builder.Append(src.Replace("\n", "\n\t")); label = src[0] == '{'; } builder.Append("\r\n}"); return(builder.ToString()); }
/// <summary> /// ContextCondition を C# のコードに変換します。 /// </summary> /// <param name="cc">現在使用している ContextCompiler を指定します。</param> /// <returns>Boolean 値を返す条件式を C# で表現して返します。 /// default の場合 (どんな場合でも受容する場合) には "" を返します。</returns> public string ToCSharpSource(ContextCompiler cc) { if (this.word == "<def>") { return(""); } if (this.word == "<nul>") { return("(this.wreader.CurrentType.value==" + WordType.Invalid.value.ToString() + ")"); } if (this.word == "") { if (this.wordtype == "") { throw new System.ApplicationException("Fatal: ここに制御は来ない筈…ContextWordReader が空文字列の Identifier を返さぬ限り"); } return("(" + this._wordtype + ")"); } else { string r = this.wordtype == ""?"(":"(" + this._wordtype + "&&"; return(r + "word==" + this.word_quoted + ")"); } }
/// <summary> /// ContextStage の内容を C# コードにします。 /// </summary> /// <param name="cc">今日は</param> /// <returns>分岐条件がある場合には if(<分岐条件>) で始まるコードを返します。 /// 分岐条件が無く default の場合には { で始まるコードを返します。</returns> public string ToCSharpSource(ContextCompiler cc) { System.Text.StringBuilder builder = new System.Text.StringBuilder(); if (words.Count == 0) { if (this.cmds.Count == 0) { throw new System.ApplicationException("Fatal: ここに制御は来ない筈…ContextStage.Read を見よ"); } object key = this.cmds[0]; cc.wreader.LetterReader.SetError("命令に対応する分岐標がないです。", key, key); return(""); } //条件式の入り口 // 条件のある時: if(何とかかんとか){ // <def>条件の時: { builder.Append("if("); bool def = false; bool firstword = true; foreach (ContextCondition w in words) { if (w.word == "<def>") { if (words.Count > 1) { this.SetErrorButDefault(cc.wreader.LetterReader); } builder = new System.Text.StringBuilder(); builder.Append("{\r\n\t"); def = true; break; } else { if (firstword) { firstword = false; } else { builder.Append("||"); } builder.Append(w.ToCSharpSource(cc)); } } if (!def) { builder.Append("){\r\n\t"); } //中身 bool last = false; foreach (ContextCommand c in cmds) { builder.Append(c.ToCSharpSource(cc, ref last).Replace("\n", "\n\t")); } //末端 if (builder[builder.Length - 1] == '\t') { builder[builder.Length - 1] = '}'; } else { builder.Append('}'); } return(builder.ToString()); }
public static bool Read(ContextCompiler p, out Context context) { if (p.wreader.CurrentType == WordType.Invalid) { context = new Context(); return(false); } context = new Context(); context.data = new Gen::List <ContextStage>(); // context while (p.wreader.CurrentType != WordType.Identifier || p.wreader.CurrentWord != "context") { p.wreader.LetterReader.SetError("context の開始には keyword 'context' が必要です。", 0, null); if (!p.wreader.ReadNext()) { return(false); } } p.wreader.ReadNext(); // ContextName while (p.wreader.CurrentType != WordType.Identifier) { p.wreader.LetterReader.SetError("keyword 'context' の後には識別子が必要です。", 0, null); if (!p.wreader.ReadNext()) { return(false); } } context.name = p.wreader.CurrentWord; if (!context.CheckName()) { p.wreader.LetterReader.SetError("指定した識別子は識別子として無効です。適切な物を指定して下さい", 0, null); } p.wreader.ReadNext(); // { while (p.wreader.CurrentType != WordType.Operator || p.wreader.CurrentWord != "{") { p.wreader.LetterReader.SetError("context 宣言の後には context の中身が必要です。中身は { で始めて下さい。", 0, null); if (!p.wreader.ReadNext()) { return(false); } } p.wreader.ReadNext(); // List<ContextStage> ContextStage stage; while (ContextStage.Read(p, out stage)) { context.data.Add(stage); } // } if (p.wreader.CurrentType == WordType.Operator && p.wreader.CurrentWord == "}") { p.wreader.ReadNext(); } return(true); }
public string ToCSharpSource(ContextCompiler cc, string argument) { return(this.content); }
public string ToCSharpSource(ContextCompiler cc, string argument) { return(this.hasargument?this.content.Replace("$$", argument):this.content); }