Ejemplo n.º 1
0
 /// <summary>
 /// コンストラクタ
 /// </summary>
 /// <param name="tokens"></param>
 public NakoParserBase(NakoTokenList tokens)
 {
     this.tok = tokens;
     tokens.MoveTop();
     parentNode        = topNode = new NakoNode();
     frameStack        = new Stack <NakoParserFrame>();
     stateStack        = new Stack <NakoParserNodeState>();
     calcStack         = new NakoNodeList();
     calcStackCounters = new Stack <int>();
     lastNode          = null;
     localVar          = new NakoVariableManager(NakoVariableScope.Local);
 }
Ejemplo n.º 2
0
 /// <summary>
 /// コンストラクタ
 /// </summary>
 /// <param name="tokens"></param>
 public NakoParserBase(NakoTokenList tokens)
 {
     this.tok = tokens;
     tokens.MoveTop();
     parentNode = topNode = new NakoNode();
     frameStack = new Stack<NakoParserFrame>();
     stateStack = new Stack<NakoParserNodeState>();
     calcStack = new NakoNodeList();
     calcStackCounters = new Stack<int>();
     lastNode = null;
     localVar = new NakoVariableManager(NakoVariableScope.Local);
 }
Ejemplo n.º 3
0
        //> _arglist : '(' { _value } ')'
        //>          ;
        private bool _arglist(NakoNodeCallFunction node)
        {
            NakoToken firstT = tok.CurrentToken;
            int       nest   = 0;

            // '(' から始まるかチェック
            if (!Accept(NakoTokenType.PARENTHESES_L))
            {
                return(false);
            }
            tok.MoveNext(); // skip '('
            nest++;

            // '(' .. ')' の間を取りだして別トークンとする
            NakoTokenList par_list = new NakoTokenList();

            while (!tok.IsEOF())
            {
                if (Accept(NakoTokenType.PARENTHESES_R))
                {
                    nest--;
                    if (nest == 0)
                    {
                        tok.MoveNext();
                        break;
                    }
                }
                else if (Accept(NakoTokenType.PARENTHESES_L))
                {
                    nest++;
                }
                par_list.Add(tok.CurrentToken);
                tok.MoveNext();
            }
            // 現在のトークン位置を保存
            tok.Save();
            NakoTokenList tmp_list = tok;

            tok = par_list;
            tok.MoveTop();
            while (!tok.IsEOF())
            {
                if (!_value())
                {
                    throw new NakoParserException("関数の引数の配置エラー。", firstT);
                }
            }
            // トークンリストを復元
            tok = tmp_list;
            tok.Restore();
            return(true);
        }
Ejemplo n.º 4
0
        //> _def_function_args : empty
        //>                    | '(' { WORD } ')' FUNCTION_NAME
        //>                    | { WORD } FUNCTION_NAME
        //>                    | FUNCTION_NAME '(' { WORD } ')'
        //>                    ;
        private bool _def_function_args(NakoFunc func)
        {
            NakoToken     firstT    = tok.CurrentToken;
            NakoTokenList argTokens = new NakoTokenList();
            bool          argMode   = false;
            NakoToken     funcName  = null;

            // 関数の引数宣言を取得する
            while (!tok.IsEOF())
            {
                // '(' .. ')' の中は全部、関数の引数です
                if (argMode)
                {
                    if (Accept(NakoTokenType.PARENTHESES_R))
                    {
                        argMode = false;
                        tok.MoveNext();
                        continue;
                    }
                    argTokens.Add(tok.CurrentToken);
                    tok.MoveNext();
                    continue;
                }
                if (Accept(NakoTokenType.PARENTHESES_L))
                {
                    tok.MoveNext();
                    argMode = true;
                    continue;
                }
                if (Accept(NakoTokenType.SCOPE_BEGIN))
                {
                    break;
                }
                if (Accept(NakoTokenType.FUNCTION_NAME))
                {
                    funcName = tok.CurrentToken;
                    tok.MoveNext();
                    continue;
                }
                argTokens.Add(tok.CurrentToken);
                tok.MoveNext();
            }
            if (funcName == null)
            {
                throw new NakoParserException("関数名がありません。", firstT);
            }
            func.name = funcName.GetValueAsName();            //TODO: check namespace and class name
            func.args.analizeArgTokens(argTokens);
            return(true);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// 引数の定義文字列を読んで、関数の引数として登録する
        /// </summary>
        public void analizeArgTokens(NakoTokenList tokens)
        {
            bool   optMode = false;
            ArgOpt argOpt  = new ArgOpt();

            for (int i = 0; i < tokens.Count; i++)
            {
                NakoToken   tok = tokens[i];
                NakoFuncArg arg = null;
                // オプション指定モード(optMode) の on/off
                if (tok.Type == NakoTokenType.BRACES_L)
                {
                    // オプションの初期化
                    optMode = true;
                    argOpt.Init();
                    continue;
                }
                if (tok.Type == NakoTokenType.BRACES_R)
                {
                    optMode = false;
                    continue;
                }
                if (optMode)
                {
                    if (tok.Type == NakoTokenType.WORD)
                    {
                        string opt = (string)tok.Value;
                        if (opt == "参照渡し")
                        {
                            argOpt.varBy = VarByType.ByRef;
                        }
                        if (opt == "整数")  //TODO:数値
                        {
                            NakoToken checkToken = tokens [i + 1];
                            if (checkToken.Type == NakoTokenType.EQ)
                            {
                                checkToken = tokens [i + 2];
                                if (checkToken.Type == NakoTokenType.INT)
                                {
                                    argOpt.defaultValue = int.Parse(checkToken.Value);
                                }
                            }
                        }
                        if (opt == "文字列")
                        {
                            NakoToken checkToken = tokens [i + 1];
                            if (checkToken.Type == NakoTokenType.EQ)
                            {
                                checkToken = tokens [i + 2];
                                if (checkToken.Type == NakoTokenType.STRING || checkToken.Type == NakoTokenType.STRING_EX || checkToken.Type == NakoTokenType.WORD)
                                {
                                    argOpt.defaultValue = (string)checkToken.Value;
                                }
                            }
                        }
                    }
                    else
                    {
                        //find type
                        string type  = (string)tok.Value;
                        int    index = NakoAPIFuncBank.Instance.FuncList.FindIndex(delegate(NakoAPIFunc obj) {
                            return(obj.PluginInstance.Name == type);
                        });
                        if (index > 0)
                        {
                            argOpt.type = type;
                        }
                    }
                    continue;
                }

                // WORD
                if (tok.Type == NakoTokenType.WORD)
                {
                    int idx = indexOfName(tok.Value);
                    if (idx < 0)
                    {
                        arg              = new NakoFuncArg();
                        arg.name         = tok.Value;
                        arg.varBy        = argOpt.varBy;
                        arg.defaultValue = argOpt.defaultValue;
                        arg.type         = argOpt.type;
                        arg.AddJosi(tok.Josi);
                        this.Add(arg);
                        argOpt.Init();
                    }
                    else
                    {
                        arg = this[idx];
                        arg.AddJosi(tok.Josi);
                    }
                }
                if (tok.Type == NakoTokenType.OR || tok.Type == NakoTokenType.OR_OR)
                {
                    continue;
                }
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// 引数の定義文字列を読んで、関数の引数として登録する
        /// </summary>
        /// <param name="str"></param>
        public void analizeArgStr(string str)
        {
            NakoTokenList tokens = NakoTokenization.TokenizeSplitOnly(str);

            analizeArgTokens(tokens);
        }
Ejemplo n.º 7
0
 /// <summary>
 /// 字句解析(トークンの分割)を行う
 /// 結果は Tokens で得られる
 /// </summary>
 public void Tokenize()
 {
     tokens = NakoTokenization.Tokenize(source, TokenDic);
 }
Ejemplo n.º 8
0
 /// <summary>
 /// 字句解析(トークンの分割)を行う
 /// 結果は Tokens で得られる
 /// </summary>
 public void Tokenize()
 {
     tokens = NakoTokenization.Tokenize(source, TokenDic);
 }
Ejemplo n.º 9
0
        /// <summary>
        /// 引数の定義文字列を読んで、関数の引数として登録する
        /// </summary>
        public void analizeArgTokens(NakoTokenList tokens)
        {
            bool   optMode = false;
            ArgOpt argOpt  = new ArgOpt();

            for (int i = 0; i < tokens.Count; i++)
            {
                NakoToken   tok = tokens[i];
                NakoFuncArg arg = null;
                // オプション指定モード(optMode) の on/off
                if (tok.Type == NakoTokenType.BRACES_L)
                {
                    // オプションの初期化
                    optMode = true;
                    argOpt.Init();
                    continue;
                }
                if (tok.Type == NakoTokenType.BRACES_R)
                {
                    optMode = false;
                    continue;
                }
                if (optMode)
                {
                    if (tok.Type == NakoTokenType.DIM_INT)   //ユーザー定義関数の「整数」はDIM INTと判定されるので、WORDに直す
                    {
                        tok.Type = NakoTokenType.WORD;
                    }
                    if (tok.Type == NakoTokenType.WORD)
                    {
                        string opt = (string)tok.Value;
                        if (opt == "参照渡し")
                        {
                            argOpt.varBy = VarByType.ByRef;
                        }
                        if (opt == "整数")  //TODO:数値
                        {
                            NakoToken checkToken = tokens [i + 1];
                            if (checkToken.Type == NakoTokenType.EQ)
                            {
                                checkToken = tokens [i + 2];
                                if (checkToken.Type == NakoTokenType.INT)
                                {
                                    argOpt.defaultValue = int.Parse(checkToken.Value);
                                }
                            }
                        }
                        if (opt == "文字列")
                        {
                            NakoToken checkToken = tokens [i + 1];
                            if (checkToken.Type == NakoTokenType.EQ)
                            {
                                checkToken = tokens [i + 2];
                                if (checkToken.Type == NakoTokenType.STRING || checkToken.Type == NakoTokenType.STRING_EX || checkToken.Type == NakoTokenType.WORD)
                                {
                                    argOpt.defaultValue = (string)checkToken.Value;
                                }
                            }
                        }
                        if (opt == "関数")  //関数定義が引数の場合。{関数(2)}とか表記(n)はn個引数があるという意味。初期値は無いはずなので、引数の個数をdefaultValueプロパティに入れているが、その点は修正の必要があるかもしれない。
                        {
                            argOpt.defaultValue = 0;
                            argOpt.type         = NakoFuncType.UserCall.ToString();
                            for (int j = i + 1; j < tokens.Count; j++)
                            {
                                if (tokens [j].Type == NakoTokenType.PARENTHESES_L)
                                {
                                    j++;
                                    NakoToken argCountToken = tokens [j];
                                    argOpt.defaultValue = int.Parse(argCountToken.Value);
                                    j++;
                                }
                                if (tokens [j].Type == NakoTokenType.BRACES_R)
                                {
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        //find type
                        string type  = (string)tok.Value;
                        int    index = NakoAPIFuncBank.Instance.FuncList.FindIndex(delegate(NakoAPIFunc obj) {
                            return(obj.PluginInstance.Name == type);
                        });
                        if (index > 0)
                        {
                            argOpt.type = type;
                        }
                    }
                    continue;
                }

                // WORD
                if (tok.Type == NakoTokenType.WORD)
                {
                    int idx = indexOfName(tok.Value);
                    if (idx < 0)
                    {
                        arg              = new NakoFuncArg();
                        arg.name         = tok.Value;
                        arg.varBy        = argOpt.varBy;
                        arg.defaultValue = argOpt.defaultValue;
                        arg.type         = argOpt.type;
                        arg.AddJosi(tok.Josi);
                        this.Add(arg);
                        argOpt.Init();
                    }
                    else
                    {
                        arg = this[idx];
                        arg.AddJosi(tok.Josi);
                    }
                }
                if (tok.Type == NakoTokenType.OR || tok.Type == NakoTokenType.OR_OR)
                {
                    continue;
                }
            }
        }
Ejemplo n.º 10
0
        //> _def_function_args : empty
        //>                    | '(' { WORD } ')' FUNCTION_NAME
        //>                    | { WORD } FUNCTION_NAME
        //>                    | FUNCTION_NAME '(' { WORD } ')'
        //>                    ;
        private bool _def_function_args(NakoFunc func)
        {
            NakoToken firstT = tok.CurrentToken;
            NakoTokenList argTokens = new NakoTokenList();
            bool argMode = false;
            NakoToken funcName = null;

            // 関数の引数宣言を取得する
            while (!tok.IsEOF())
            {
                // '(' .. ')' の中は全部、関数の引数です
                if (argMode)
                {
                    if (Accept(NakoTokenType.PARENTHESES_R))
                    {
                        argMode = false;
                        tok.MoveNext();
                        continue;
                    }
                    argTokens.Add(tok.CurrentToken);
                    tok.MoveNext();
                    continue;
                }
                if (Accept(NakoTokenType.PARENTHESES_L))
                {
                    tok.MoveNext();
                    argMode = true;
                    continue;
                }
                if (Accept(NakoTokenType.SCOPE_BEGIN)) break;
                if (Accept(NakoTokenType.FUNCTION_NAME))
                {
                    funcName = tok.CurrentToken;
                    tok.MoveNext();
                    continue;
                }
                argTokens.Add(tok.CurrentToken);
                tok.MoveNext();
            }
            if (funcName == null) { throw new NakoParserException("関数名がありません。", firstT); }
            func.name = funcName.GetValueAsName();//TODO: check namespace and class name
            func.args.analizeArgTokens(argTokens);
            return true;
        }
Ejemplo n.º 11
0
 /// <summary>
 /// 構文解析器のコンストラクタ
 /// </summary>
 /// <param name="tokens"></param>
 public NakoParser(NakoTokenList tokens)
     : base(tokens)
 {
 }
Ejemplo n.º 12
0
        //> _arglist : '(' { _value } ')'
        //>          ;
        private bool _arglist(NakoNodeCallFunction node)
        {
            NakoToken firstT = tok.CurrentToken;
            int nest = 0;
            // '(' から始まるかチェック
            if (!Accept(NakoTokenType.PARENTHESES_L))
            {
                return false;
            }
            tok.MoveNext(); // skip '('
            nest++;

            // '(' .. ')' の間を取りだして別トークンとする
            NakoTokenList par_list = new NakoTokenList();
            while (!tok.IsEOF())
            {
                if (Accept(NakoTokenType.PARENTHESES_R))
                {
                    nest--;
                    if (nest == 0)
                    {
                        tok.MoveNext();
                        break;
                    }
                }
                else if (Accept(NakoTokenType.PARENTHESES_L))
                {
                    nest++;
                }
                par_list.Add(tok.CurrentToken);
                tok.MoveNext();
            }
            // 現在のトークン位置を保存
            tok.Save();
            NakoTokenList tmp_list = tok;
            tok = par_list;
            tok.MoveTop();
            while (!tok.IsEOF())
            {
                if (!_value())
                {
                    throw new NakoParserException("関数の引数の配置エラー。", firstT);
                }
            }
            // トークンリストを復元
            tok = tmp_list;
            tok.Restore();
            return true;
        }
Ejemplo n.º 13
0
 /// <summary>
 /// NakoTokenizer クラスの新しいインスタンスを初期化します。
 /// </summary>
 public NakoTokenizer()
 {
     tokens = new NakoTokenList();
     indentStack = new Stack<int>();
 }
Ejemplo n.º 14
0
 /// <summary>
 /// 展開あり文字列トークンを再帰的に展開します。
 /// </summary>
 /// <param name="token">展開あり文字列トークン。</param>
 /// <returns>再帰的に展開したトークン一覧。</returns>
 private static NakoTokenList StringTokenExtract(NakoToken token)
 {
     var tokens = new NakoTokenList();
     string tmp = "";
     string str = token.Value;
     int i = 0;
     bool isFirst = true;
     while (i < str.Length)
     {
         char ch = str[i];
         if (ch == '{' || ch == '{')
         {
             if (isFirst)
             {
                 isFirst = false;
             }
             else
             {
                 // "&" トークンを追加
                 tokens.Add(new NakoToken(NakoTokenType.AND, token.LineNo, token.IndentLevel));
             }
             i++;
             // 展開する文字列 ("{" と "}" との間) を取得する
             string exString = "";
             {
                 char end = (ch == '{') ? '}' : '}';
                 for (; i < str.Length; i++)
                 {
                     if (str[i] == end)
                     {
                         i++;
                         break;
                     }
                     exString += str[i];
                 }
             }
             // 文字列展開だけの特殊メソッド ('\' メソッド)
             if (exString.Length > 0 && exString[0] == '\\')
             {
                 if (exString == "\\t")
                 {
                     // \t の場合
                     tmp += '\t';
                     exString = "";
                 }
                 else if (exString == "\\r")
                 {
                     // \r の場合
                     tmp += '\r';
                     exString = "";
                 }
                 else if (exString == "\\n")
                 {
                     // \n の場合
                     tmp += '\n';
                     exString = "";
                 }
                 else if (NakoUtility.IsNumber(exString[1]))
                 {
                     // \0 のような場合
                     exString = exString.Substring(1);
                     tmp += (char)int.Parse(exString);
                     exString = "";
                 }
                 else if (exString[1] == '$')
                 {
                     // \$00 のような場合
                     exString = "0x" + exString.Substring(2);
                     tmp += (char)int.Parse(exString);
                     exString = "";
                 }
                 else
                 {
                     new NakoTokenizerException("展開あり文字列内の利用できない`\\'メソッド:" + exString, token);
                 }
             }
             // 文字列展開だけの特殊メソッド ('~' メソッド)
             else if (exString.Length == 1 && exString[0] == '~')
             {
                 tmp += "\r\n";
                 exString = "";
             }
             // 文字列トークンを追加
             tokens.Add(new NakoToken(NakoTokenType.STRING, token.LineNo, token.IndentLevel, tmp));
             tmp = "";
             if (exString != "")
             {
                 // "&" トークンを追加
                 tokens.Add(new NakoToken(NakoTokenType.AND, token.LineNo, token.IndentLevel));
                 // "(" トークンを追加
                 tokens.Add(new NakoToken(NakoTokenType.PARENTHESES_L, token.LineNo, token.IndentLevel));
                 // 再帰的にトークンを解析
                 var innerTokens = new NakoTokenizer().TokenizeSplitOnly(exString, token.LineNo, token.IndentLevel); // とりあえず区切るだけ
                 foreach (var innerToken in innerTokens)
                 {
                     tokens.Add(innerToken);
                 }
                 // ")" トークンを追加
                 tokens.Add(new NakoToken(NakoTokenType.PARENTHESES_R, token.LineNo, token.IndentLevel));
             }
             continue;
         }
         tmp += ch;
         i++;
     }
     if (tmp != "")
     {
         if (!isFirst)
         {
             // "&" トークンを追加
             tokens.Add(new NakoToken(NakoTokenType.AND, token.LineNo, token.IndentLevel));
         }
         // 文字列トークンを追加
         tokens.Add(new NakoToken(NakoTokenType.STRING, token.LineNo, token.IndentLevel, tmp));
     }
     else
     {
         // 必要なら空文字列トークンを追加
         if (isFirst)
         {
             tokens.Add(new NakoToken(NakoTokenType.STRING, token.LineNo, token.IndentLevel, ""));
         }
     }
     // 助詞をコピー
     tokens[tokens.Count - 1].Josi = token.Josi;
     return tokens;
 }
Ejemplo n.º 15
0
 /// <summary>
 /// 構文解析器のコンストラクタ
 /// </summary>
 /// <param name="tokens"></param>
 public NakoParser(NakoTokenList tokens) : base(tokens)
 {
 }