Ejemplo n.º 1
0
        public static ASTNode Compile(string source)
        {
            ScriptParseContext ctx = new ScriptParseContext {
                lexer = new Lexer(new StringReader(source),
                                  new TokenDefinition[] {
                    TD_SPACE,
                    TD_COMMENT,
                    TD_INT,
                    TD_FLOAT,
                    TD_BOOL,
                    TD_STR,
                    TD_ID,
                    TD_LEFT_BRACE,
                    TD_RIGHT_BRACE,
                    TD_LEFT_PAREN,
                    TD_RIGHT_PAREN,
                    TD_COMMA,
                    TD_AT,
                    TD_QUESTION,
                    TD_SEMI,
                    TD_GTEQ,
                    TD_LTEQ,
                    TD_GT,
                    TD_LT,
                    TD_EQ,
                    TD_NEQ,
                    TD_ASSIGN,
                    TD_COLON,
                    TD_EXCLAIM
                }
                                  ),
            };

            var t1  = DateTime.Now;
            var ret = ParseNode(ctx);
            var t2  = DateTime.Now;

            Debug.Log("[BTScript] Compilation took " + (t2 - t1).Milliseconds + " ms.");
            return(ret);
        }
Ejemplo n.º 2
0
        static ASTNode ParseNode(ScriptParseContext ctx)
        {
            var lexer = ctx.lexer;

            string head      = _Expect(lexer, TK_ID, TK_COLON, TK_AT, TK_QUESTION, TK_EXCLAIM);
            object headToken = lexer.Token;

            if (headToken == TK_ID)   // Control node
            {
                var nodeName = head;

                var node = ASTControlNode.Create(nodeName, lexer.LineNumber);

                _Expect(lexer, TK_LEFT_BRACE);
                while (true)   // parse child nodes
                {
                    ASTNode n = ParseNode(ctx);
                    node.children.Add(n);

                    // Peek next lexeme
                    _Expect(lexer, TK_ID, TK_COLON, TK_AT, TK_QUESTION, TK_RIGHT_BRACE, TK_EXCLAIM);

                    if (lexer.Token == TK_RIGHT_BRACE)
                    {
                        break;
                    }

                    lexer.PushCurrent();  // Save last token for subsequent parsing
                }

                return(node);
            }
            else if (headToken == TK_COLON)     // Decorator node
            {
                string nodeName = _Expect(lexer, TK_ID);

                var node = ASTDecoratorNode.Create(nodeName, lexer.LineNumber);

                _Expect(lexer, TK_LEFT_PAREN, TK_ID, TK_AT, TK_QUESTION, TK_COLON, TK_EXCLAIM);
                if (lexer.Token == TK_LEFT_PAREN)
                {
                    while (true)
                    {
                        var look2 = _Expect(lexer, TK_RIGHT_PAREN, TK_INT, TK_FLOAT, TK_STR);
                        if (lexer.Token == TK_RIGHT_PAREN)
                        {
                            break;
                        }
                        else
                        {
                            object arg;
                            if (lexer.Token == TK_INT)
                            {
                                arg = int.Parse(look2);
                            }
                            else if (lexer.Token == TK_FLOAT)
                            {
                                arg = float.Parse(look2);
                            }
                            else     // TK_STR
                            {
                                arg = look2.Substring(1, look2.Length - 2);
                            }

                            node.args.Add(new SerializableArg(arg));

                            _Expect(lexer, TK_COMMA, TK_RIGHT_PAREN);
                            if (lexer.Token == TK_RIGHT_PAREN)
                            {
                                lexer.PushCurrent();
                            }
                        }
                    }
                }
                else
                {
                    lexer.PushCurrent();
                }

                node.target = ParseNode(ctx);

                return(node);
            }
            else if (headToken == TK_AT)     // Action node
            {
                string actionName = _Expect(lexer, TK_ID);
                var    node       = ASTActionNode.Create(actionName, lexer.LineNumber);

                _Expect(lexer, TK_LEFT_PAREN, TK_SEMI);
                if (lexer.Token == TK_SEMI)
                {
                    return(node);
                }
                else
                {
                    while (true)
                    {
                        string look1 = _Expect(lexer, TK_RIGHT_PAREN, TK_ID);
                        if (lexer.Token == TK_RIGHT_PAREN)
                        {
                            break;
                        }
                        else
                        {
                            string argName = look1;

                            _Expect(lexer, TK_ASSIGN);

                            object arg = ParseArg(lexer);

                            var wrapped = new SerializableArgPair {
                                name = argName,
                                arg  = new SerializableArg(arg)
                            };
                            node.args.Add(wrapped);

                            _Expect(lexer, TK_COMMA, TK_RIGHT_PAREN);
                            if (lexer.Token == TK_RIGHT_PAREN)
                            {
                                lexer.PushCurrent();
                            }
                        }
                    }

                    _Expect(lexer, TK_SEMI);
                    return(node);
                }
            }
            else if (headToken == TK_EXCLAIM)
            {
                string argName = _Expect(lexer, TK_ID);
                _Expect(lexer, TK_ASSIGN);
                object arg = ParseArg(lexer);
                _Expect(lexer, TK_SEMI);

                var node = ASTSetConditionNode.Create(lexer.LineNumber);
                node.condName = argName;
                node.arg      = new SerializableArg(arg);
                return(node);
            }
            else     // TK_QUESTION, Condition node
            {
                Debug.Assert(headToken == TK_QUESTION);

                string tk = _Expect(lexer, TK_EXCLAIM, TK_ID);

                string condName;

                if (lexer.Token != TK_EXCLAIM)
                {
                    condName = tk;

                    _Expect(lexer, TK_SEMI, TK_LTEQ, TK_LT, TK_GTEQ, TK_GT, TK_EQ, TK_NEQ);
                    if (lexer.Token == TK_SEMI)   // boolean condition node
                    {
                        var node = ASTConditionNode.Create(lexer.LineNumber);
                        node.condName     = condName;
                        node.arg.objValue = true;
                        return(node);
                    }
                    else     // value condition node
                    {
                        CompareOp op = GetCompareOp(lexer.Token as TokenType);

                        string val      = _Expect(lexer, TK_FLOAT, TK_INT);
                        var    floatVal = float.Parse(val);

                        var node = ASTConditionNode.Create(lexer.LineNumber);
                        node.condName     = condName;
                        node.arg.objValue = floatVal;
                        node.op           = op;

                        _Expect(lexer, TK_SEMI);

                        return(node);
                    }
                }
                else
                {
                    condName = _Expect(lexer, TK_ID);

                    if (lexer.Token == TK_ID)
                    {
                        var conditionNode = ASTConditionNode.Create(lexer.LineNumber);
                        conditionNode.condName = condName;
                        conditionNode.arg.type = ConditionType.Bool;
                        conditionNode.op       = CompareOp.NotEq;
                        _Expect(lexer, TK_SEMI);
                        return(conditionNode);
                    }
                    else
                    {
                        throw _Error(lexer, "only bool varible can be place after '? !'");
                    }
                }
            }
        }