Beispiel #1
0
        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");
            }
        }
Beispiel #2
0
 public string ToCSharpSource(ContextCompiler cc, string argument)
 {
     if (!cc.ContainsContext(argument))
     {
         throw new System.ArgumentException("指定した名前  '" + argument + "' という Context は定義されていません。", "argument");
     }
     return("this.ReadContext_" + argument + "();\r\n");
 }
Beispiel #3
0
        /// <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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
 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");
     }
 }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        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");
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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());
        }
Beispiel #11
0
 /// <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 + ")");
     }
 }
Beispiel #12
0
        /// <summary>
        /// ContextStage の内容を C# コードにします。
        /// </summary>
        /// <param name="cc">今日は</param>
        /// <returns>分岐条件がある場合には if(&lt;分岐条件&gt;) で始まるコードを返します。
        /// 分岐条件が無く 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());
        }
Beispiel #13
0
        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);
        }
Beispiel #14
0
 public string ToCSharpSource(ContextCompiler cc, string argument)
 {
     return(this.content);
 }
Beispiel #15
0
 public string ToCSharpSource(ContextCompiler cc, string argument)
 {
     return(this.hasargument?this.content.Replace("$$", argument):this.content);
 }