Example #1
0
 static void HandleRecord(ref Token token, FCodeLuaFunction f, int lineNumber)
 {
     if (f != null && !(token is JumpToken))
     {
         var t   = f.tokens;
         var l2t = f.line2Tokens;
         lineNumber = lineNumber - f.fileStartLine + 1;
         f.maxLine  = Math.Max(f.maxLine, lineNumber);
         HandlerRecord(ref token, ref t, ref l2t, lineNumber);
     }
 }
Example #2
0
        public static FCodeLuaFunction GenFunction(string word)
        {
            var func = new FCodeLuaFunction(0)
            {
                name = word, shortName = word
            };
            var functionStart = new List <Token>()
            {
                new TypedToken(TK.FUNCTION), new LiteralToken('('), new LiteralToken(')')
            };
            var functionEnd = new List <Token>()
            {
                new TypedToken(TK.END)
            };

            func.line2Tokens.Add(1, functionStart);
            func.line2Tokens.Add(2, functionEnd);
            func.tokens.AddRange(functionStart);
            func.tokens.AddRange(functionEnd);
            return(func);
        }
Example #3
0
        static void ParseSingleLogic(Dictionary <int, List <Token> > line2Tokens, int startLine, int endLine, ref List <FCodeLuaFunction> functions, ref FCodeLogic logic)
        {
            FCodeWindow w = EditorWindow.GetWindow <FCodeWindow>();
            Dictionary <string, string> fcodeSignature = w.fcodeSignature;
            var              isSingleLogicStarted      = false;
            FCodeTiming      timing = 0;
            FCodeLuaFunction command = null, condition = null;

            for (int currentLine = startLine + 1; currentLine < endLine; currentLine++)
            {
                if (line2Tokens.TryGetValue(currentLine, out List <Token> lineContent))
                {
                    // ** 从签名开始处
                    if (!isSingleLogicStarted)
                    {
                        isSingleLogicStarted = ValidSignature(lineContent, fcodeSignature, "SingleLogicStart");
                        continue;
                    }
                    else if (ValidSignature(lineContent, fcodeSignature, "SingleLogicStart"))
                    {
                        Error("重复的FCodeSignature:SingleLogic:Start签名??");
                    }

                    // ** 从签名开始的下一行 直到签名结束的行内容都会在此处解析
                    var s = lineContent[0].Original();
                    switch (s)
                    {
                    case "timing":
                        var end = lineContent.Find(item => item.Original() == "FCodeTiming");
                        if (end != null)
                        {
                            var index = lineContent.IndexOf(end);
                            if (!Enum.TryParse(lineContent[index + 2].Original(), out timing))
                            {
                                Error($"解析FCodeTiming字符串出错 未定义的 {lineContent[index + 2].Original()}??");
                            }
                        }
                        else
                        {
                            Error("timing 字段中 未找到FCodeTiming关键字??");
                        }
                        break;

                    case "command":
                        command = functions?.Find(luaFunc => luaFunc.fileStartLine == currentLine);
                        break;

                    case "condition":
                        condition = functions?.Find(luaFunc => luaFunc.fileStartLine == currentLine);
                        break;
                    }

                    // ** 到签名结束
                    if (ValidSignature(lineContent, fcodeSignature, "SingleLogicEnd"))
                    {
                        isSingleLogicStarted = false;
                        var singleLogic = new FCodeLogic.SingleLogic(timing, command ?? GenFunction("command"), condition ?? GenFunction("condition"));
                        command   = null;
                        condition = null;
                        logic.logicList.Add(singleLogic);
                    }
                }
            }
        }
Example #4
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);
        }