示例#1
0
        private static WordCollection expandMacro(WordCollection wc)
        {
            //マクロ展開
            wc.Pointer = 0;
            int count = 0;

            while (!wc.EOL)
            {
                IdentifierWord word = wc.Current as IdentifierWord;
                if (word == null)
                {
                    wc.ShiftNext();
                    continue;
                }
                string      idStr = word.Code;
                DefineMacro macro = GlobalStatic.IdentifierDictionary.GetMacro(idStr);
                if (macro == null)
                {
                    wc.ShiftNext();
                    continue;
                }
                count++;
                if (count > MAX_EXPAND_MACRO)
                {
                    throw new CodeEE("マクロの展開数が1文あたりの上限" + MAX_EXPAND_MACRO.ToString() + "を超えました(自己参照・循環参照のおそれ)");
                }
                if (!macro.HasArguments)
                {
                    wc.Remove();
                    wc.InsertRange(macro.Statement);
                    continue;
                }
                //関数型マクロ
                wc = expandFunctionlikeMacro(macro, wc);
            }
            wc.Pointer = 0;
            return(wc);
        }
示例#2
0
        private static WordCollection expandFunctionlikeMacro(DefineMacro macro, WordCollection wc)
        {
            int macroStart = wc.Pointer;

            wc.ShiftNext();
            SymbolWord symbol = wc.Current as SymbolWord;

            if (symbol == null || symbol.Type != '(')
            {
                throw new CodeEE("関数形式のマクロ" + macro.Keyword + "に引数がありません");
            }
            WordCollection macroWC = macro.Statement.Clone();

            WordCollection[] args = new WordCollection[macro.ArgCount];
            //引数部読み取りループ
            for (int i = 0; i < macro.ArgCount; i++)
            {
                int macroNestBracketS = 0;
                args[i] = new WordCollection();
                while (true)
                {
                    wc.ShiftNext();
                    if (wc.EOL)
                    {
                        throw new CodeEE("関数形式のマクロ" + macro.Keyword + "の用法が正しくありません");
                    }
                    symbol = wc.Current as SymbolWord;
                    if (symbol == null)
                    {
                        args[i].Add(wc.Current);
                        continue;
                    }
                    switch (symbol.Type)
                    {
                    case '(': macroNestBracketS++; break;

                    case ')':
                        if (macroNestBracketS > 0)
                        {
                            macroNestBracketS--;
                            break;
                        }
                        if (i != macro.ArgCount - 1)
                        {
                            throw new CodeEE("関数形式のマクロ" + macro.Keyword + "の引数の数が正しくありません");
                        }
                        goto exitfor;

                    case ',':
                        if (macroNestBracketS == 0)
                        {
                            goto exitwhile;
                        }
                        break;
                    }
                    args[i].Add(wc.Current);
                }
exitwhile:
                if (args[i].Collection.Count == 0)
                {
                    throw new CodeEE("関数形式のマクロ" + macro.Keyword + "の引数を省略することはできません");
                }
                continue;
            }
            //引数部読み取りループ終端
exitfor:
            symbol = wc.Current as SymbolWord;
            if (symbol == null || symbol.Type != ')')
            {
                throw new CodeEE("関数形式のマクロ" + macro.Keyword + "の用法が正しくありません");
            }
            int macroLength = wc.Pointer - macroStart + 1;

            wc.Pointer = macroStart;
            for (int j = 0; j < macroLength; j++)
            {
                wc.Collection.RemoveAt(macroStart);
            }
            while (!macroWC.EOL)
            {
                MacroWord w = macroWC.Current as MacroWord;
                if (w == null)
                {
                    macroWC.ShiftNext();
                    continue;
                }
                macroWC.Remove();
                macroWC.InsertRange(args[w.Number]);
                macroWC.Pointer += args[w.Number].Collection.Count;
            }
            wc.InsertRange(macroWC);
            wc.Pointer = macroStart;
            return(wc);
        }
示例#3
0
        //#define FOO (~~)     id to wc
        //#define BAR($1) (~~)     idwithargs to wc(replaced)
        //#diseble FOOBAR
        //#dim piyo, i
        //#sdim puyo, j
        //static List<string> keywordsList = new List<string>();
        private void analyzeSharpDefine(StringStream st, ScriptPosition position)
        {
            //LexicalAnalyzer.SkipWhiteSpace(st);呼び出し前に行う。
            string srcID = LexicalAnalyzer.ReadSingleIdentifier(st);
            if (srcID == null)
                throw new CodeEE("置換元の識別子がありません", position);
            if (Config.ICVariable)
                srcID = srcID.ToUpper();
            bool hasArg = st.Current == '(';//引数を指定する場合には直後に(が続いていなければならない。ホワイトスペースも禁止。
            //1808a3 代入演算子許可(関数宣言用)
            WordCollection wc = LexicalAnalyzer.Analyse(st, LexEndWith.EoL, false, true);
            if (wc.EOL)
            {
                //throw new CodeEE("置換先の式がありません", position);
                //1808a3 空マクロの許可
                DefineMacro nullmac = new DefineMacro(srcID, new WordCollection(), 0);
                idDic.AddMacro(nullmac);
                return;
            }

            List<string> argID = new List<string>();
            string errMes = "";
            int errLevel = -1;
            idDic.CheckUserMacroName(ref errMes, ref errLevel, srcID);
            if (errLevel >= 0)
            {
                ParserMediator.Warn(errMes, position, errLevel);
                if (errLevel >= 2)
                {
                    noError = false;
                    return;
                }
            }
            if (hasArg)//関数型マクロの引数解析
            {
                wc.ShiftNext();//'('を読み飛ばす
                if (wc.Current.Type == ')')
                    throw new CodeEE("関数型マクロの引数を0個にすることはできません", position);
                while (!wc.EOL)
                {
                    IdentifierWord word = wc.Current as IdentifierWord;
                    if (word == null)
                        throw new CodeEE("置換元の引数指定の書式が間違っています", position);
                    word.SetIsMacro();
                    string id = word.Code;
                    if (argID.Contains(id))
                        throw new CodeEE("置換元の引数に同じ文字が2回以上使われています", position);
                    argID.Add(id);
                    wc.ShiftNext();
                    if (wc.Current.Type == ',')
                    {
                        wc.ShiftNext();
                        continue;
                    }
                    if (wc.Current.Type == ')')
                        break;
                    throw new CodeEE("置換元の引数指定の書式が間違っています", position);
                }
                if (wc.EOL)
                    throw new CodeEE("')'が閉じられていません", position);

                wc.ShiftNext();
            }
            if (wc.EOL)
                throw new CodeEE("置換先の式がありません", position);
            WordCollection destWc = new WordCollection();
            while (!wc.EOL)
            {
                destWc.Add(wc.Current);
                wc.ShiftNext();
            }
            if (hasArg)//関数型マクロの引数セット
            {
                while (!destWc.EOL)
                {
                    IdentifierWord word = destWc.Current as IdentifierWord;
                    if (word == null)
                    {
                        destWc.ShiftNext();
                        continue;
                    }
                    for (int i = 0; i < argID.Count; i++)
                    {
                        if (string.Equals(word.Code, argID[i], Config.SCVariable))
                        {
                            destWc.Remove();
                            destWc.Insert(new MacroWord(i));
                            break;
                        }
                    }
                    destWc.ShiftNext();
                }
                destWc.Pointer = 0;
            }
            if (hasArg)//1808a3 関数型マクロの封印
                throw new CodeEE("関数型マクロは宣言できません", position);
            DefineMacro mac = new DefineMacro(srcID, destWc, argID.Count);
            idDic.AddMacro(mac);
        }
示例#4
0
 private static WordCollection expandMacro(WordCollection wc)
 {
     //マクロ展開
     wc.Pointer = 0;
     int count = 0;
     while (!wc.EOL)
     {
         IdentifierWord word = wc.Current as IdentifierWord;
         if (word == null)
         {
             wc.ShiftNext();
             continue;
         }
         string idStr = word.Code;
         DefineMacro macro = GlobalStatic.IdentifierDictionary.GetMacro(idStr);
         if (macro == null)
         {
             wc.ShiftNext();
             continue;
         }
         count++;
         if (count > MAX_EXPAND_MACRO)
             throw new CodeEE("マクロの展開数が1文あたりの上限" + MAX_EXPAND_MACRO.ToString() + "を超えました(自己参照・循環参照のおそれ)");
         if (!macro.HasArguments)
         {
             wc.Remove();
             wc.InsertRange(macro.Statement);
             continue;
         }
         //関数型マクロ
         wc = expandFunctionlikeMacro(macro, wc);
     }
     wc.Pointer = 0;
     return wc;
 }