Exemple #1
0
        public static FCodeLib TokenizeFCLogic(string content, string fcodePrefix)
        {
            FCodeLLex llex = new FCodeLLex(new StringLoadInfo(content));
            Dictionary <string, object> t = Tokenizing(llex);

            if (t.TryGetValue("functions", out var ot))
            {
                var functions = (List <FCodeLuaFunction>)ot;
                Dictionary <string, string>           parametersTypeRef = new Dictionary <string, string>();
                Dictionary <string, FCodeLuaFunction> fcodeFunctions    = new Dictionary <string, FCodeLuaFunction>();
                foreach (var fcodeFunction in functions)
                {
                    // ** 如果字段有加xxxxCheck的包装形式,则CodeEditor生成方法调用时会限制参数的填写形式;
                    foreach (var entry in fcodeFunction.line2Tokens)
                    {
                        var tokens = entry.Value;
                        if (tokens.Count > 2)
                        {
                            var first   = tokens[0].Original();
                            var varName = tokens[2].Original();
                            if (first.EndsWith("Check") && !parametersTypeRef.ContainsKey(varName))
                            {
                                parametersTypeRef.Add(varName, first.Replace("Check", ""));
                            }
                        }
                    }
                    if (fcodeFunction.name != fcodeFunction.shortName)
                    {
                        if (string.IsNullOrEmpty(fcodeFunction.shortName))
                        {
                            Debug.LogWarning($"fcodeFunction : {fcodeFunction} have no name!");
                        }
                        else
                        {
                            fcodeFunctions.Add(fcodeFunction.shortName, fcodeFunction);
                        }
                    }
                }

                return(new FCodeLib()
                {
                    fcodeFunctions = fcodeFunctions, parametersTypeRef = parametersTypeRef
                });
            }
            return(new FCodeLib());
        }
Exemple #2
0
        public static FCodeLogic Tokenize(string fileName, string content)
        {
            FCodeLLex llex = new FCodeLLex(new StringLoadInfo(content));
            Dictionary <string, object> result = Tokenizing(llex);
            FCodeLogic logic = new FCodeLogic()
            {
                name = fileName
            };
            List <FCodeLuaFunction> functions = null;

            if (result.TryGetValue("functions", out var ot))
            {
                functions = (List <FCodeLuaFunction>)ot;
            }

            if (result.TryGetValue("line2Tokens", out var ol))
            {
                var line2Tokens = (Dictionary <int, List <Token> >)ol;
                var entry       = line2Tokens.FirstOrDefault(item => item.Value.Select(v => v.Original() == "logicList").Any());
                int startLine   = entry.Key;
                if (!result.TryGetValue("maxLine", out var endLine))
                {
                    endLine = startLine;
                    Error("Tokenizing中找不到返回值endLine 使用startLine作为endLine?");
                }
                ParseSingleLogic(line2Tokens, startLine, (int)endLine, ref functions, ref logic);

                // ** 找到有 vars 关键字 且 token 数量为2的行
                var enties = line2Tokens.Where(item => item.Value.Select(v => v.Original() == "vars").Any()).ToArray();
                entry = enties.FirstOrDefault(item => item.Value.Count == 2);
                if (entry.Value != null)
                {
                    startLine = entry.Key;
                    ParseVars(line2Tokens, startLine, (int)endLine, ref functions, ref logic);
                }
            }

            return(logic);
        }
Exemple #3
0
        static Dictionary <string, object> Tokenizing(FCodeLLex l)
        {
            Dictionary <string, object> result          = new Dictionary <string, object>();
            Stack <TK>   tokenStack                     = new Stack <TK>();
            List <Token> tokenHistory                   = new List <Token>();
            Dictionary <int, List <Token> > line2Tokens = new Dictionary <int, List <Token> >();
            List <FCodeLuaFunction>         functions   = new List <FCodeLuaFunction>();

            result.Add("tokenStack", tokenStack);
            result.Add("functions", functions);
            result.Add("line2Tokens", line2Tokens);
            result.Add("tokenHistory", tokenHistory);
            FCodeLuaFunction func = null;
            TK tokenType;

            do
            {
                var token = l.NextToken();
                HandlerRecord(ref token, ref tokenHistory, ref line2Tokens, l.lineNumber);
                HandleRecord(ref token, func, l.lineNumber);
                tokenType = (TK)token.tokenType;

                switch (tokenType)
                {
                case TK.FUNCTION:
                    tokenStack.Push(tokenType);
                    // ** 函数名 or 函数存放位置
                    StringBuilder functionNameOrRef = new StringBuilder();
                    func = new FCodeLuaFunction(l.lineNumber);
                    HandleRecord(ref token, func, l.lineNumber);
                    var functionTokenType = tokenType;
                    // ** forward 形式 :xxx = function(xxx)
                    // ** 非 forward 形式 : function xxx(xxx)
                    bool isForward = false;

                    // ** 尚未解析函数名的标记
                    bool isFunctionNameUnparsed = true;
                    var  index = tokenHistory.Count - 2;
                    if (index >= 0)
                    {
                        Token previousToken = FindPreviousToken(ref index, ref tokenHistory);
                        isForward = previousToken?.tokenType == '=';
                        // ** 前面还有一个函数名 或函数的存放位置 (例如存放在数组中)
                        if (isForward && index >= 0)
                        {
                            previousToken = FindPreviousToken(ref index, ref tokenHistory);
                            while (previousToken != null && index >= 0)
                            {
                                if (previousToken is NameToken || previousToken is StringToken ||
                                    previousToken.tokenType == ':' || previousToken.tokenType == '.' ||
                                    previousToken.tokenType == '[' || previousToken.tokenType == ']')
                                {
                                    functionNameOrRef.Insert(0, previousToken.Original());
                                }
                                else
                                {
                                    break;
                                }

                                previousToken = tokenHistory[index--];
                            }
                        }
                    }

                    // ** 解析函数声明部分 函数名以及参数等
                    while (functionTokenType != TK.EOS)
                    {
                        var functionBodyToken = l.NextToken();
                        HandlerRecord(ref functionBodyToken, ref tokenHistory, ref line2Tokens, l.lineNumber);
                        HandleRecord(ref functionBodyToken, func, l.lineNumber);
                        functionTokenType = (TK)functionBodyToken.tokenType;

                        isFunctionNameUnparsed = isFunctionNameUnparsed && functionBodyToken.tokenType != '(';
                        // ** 非 forward形式的函数名
                        if (isFunctionNameUnparsed && !isForward)
                        {
                            if (functionBodyToken is NameToken || functionBodyToken.tokenType == ':' ||
                                functionBodyToken.tokenType == '.')
                            {
                                var shortName = functionBodyToken.Original();
                                functionNameOrRef.Append(shortName);
                                func.shortName = shortName;
                            }
                        }
                        else if (functionBodyToken is NameToken)
                        {
                            func.functionParameters.Add(functionBodyToken);
                        }
                        else if (functionBodyToken.tokenType == ')')
                        {
                            func.name = functionNameOrRef.ToString();
                            functions.Add(func);
                            break;
                        }
                    }

                    break;

                case TK.IF:
                case TK.FOR:
                case TK.WHILE:
                    tokenStack.Push(tokenType);
                    break;

                case TK.RETURN:
                    var rTokenType = tokenType;
                    var rToken     = token;
                    while (rTokenType != TK.EOS)
                    {
                        // ** 把return 以及其后的一些 token 加到函数的tokens中
                        rToken = l.NextToken();
                        HandlerRecord(ref rToken, ref tokenHistory, ref line2Tokens, l.lineNumber);
                        HandleRecord(ref rToken, func, l.lineNumber);
                        rTokenType = (TK)rToken.tokenType;

                        if (rToken is NameToken)
                        {
                            func?.returnParameters.Add(rToken);
                        }
                        else if (rTokenType == TK.FUNCTION)
                        {
                            // ** todo 在返回值中返回function 这里还没处理
                            Tokenizing(l);
                            rTokenType = (TK)l.token.tokenType;
                        }
                        else if (rTokenType == TK.END)
                        {
                            if (tokenStack.Count > 0)
                            {
                                var tk = tokenStack.Pop();
                                func = tk != TK.FUNCTION ? func : null;
                            }

                            // ** todo 在返回值中返回function 这里还没处理
                            break;
                        }
                    }

                    break;

                case TK.END:
                    if (tokenStack.Count > 0)
                    {
                        var tk = tokenStack.Pop();
                        func = tk != TK.FUNCTION ? func : null;
                    }

                    break;
                }
            } while (tokenType != TK.EOS);

            result.Add("maxLine", l.lineNumber);
            return(result);
        }