Ejemplo n.º 1
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.º 2
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.º 3
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.º 4
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.º 5
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;
 }