예제 #1
0
파일: EUOParser.cs 프로젝트: DarkLotus/Klip
        public List <Stmt> GenerateAST()
        {
            Block currentBlock = new Block();
            var   blockstack   = new Stack <Block>();
            Token tok          = null;
            var   tree         = new List <Stmt>();
            var   running      = true;

            while (running)
            {
                try
                {
                    tok = CurrentToken;
                    CurrentIndex++;
                    if (tok == null)
                    {
                        break;
                    }
                }
                catch { }
                if (currentBlock is IfBlock ifb)
                {
                    if (IfEndsAtThisLine != -1 && tok.Line > IfEndsAtThisLine)
                    {
                        currentBlock.AddStmt(new EndIf());
                        Block block = currentBlock;

                        if (blockstack.Count > 0)
                        {
                            currentBlock = blockstack.Pop();
                            currentBlock.AddStmt(block);
                        }
                    }
                }

                switch (tok.TokenName)
                {
                case Lexer.Tokens.Call:
                    currentBlock.AddStmt(ParseCall());
                    break;

                case Lexer.Tokens.Label:
                    currentBlock.AddStmt(new Label(tok.TokenValue.TrimEnd(new[] { ':' }).ToLowerInvariant())
                    {
                        Line = tok.Line
                    });
                    CurrentIndex++;
                    break;

                case Lexer.Tokens.Goto:
                {
                    currentBlock.AddStmt(new Goto(CurrentToken.TokenValue.TrimEnd(new[] { ':' }).ToLowerInvariant())
                        {
                            Line = tok.Line
                        });
                    CurrentIndex++;

                    Block block = currentBlock;

                    /* if ( blockstack.Count > 0 && block is Func )
                     * {
                     *   currentBlock = blockstack.Pop();
                     *   currentBlock.AddStmt( block );
                     * }*/
                }
                break;

                case Lexer.Tokens.Event:
                    currentBlock.AddStmt(ParseEvent());
                    break;

                case Lexer.Tokens.FindItem:
                    currentBlock.AddStmt(ParseFindItem());
                    break;
                }

                if (tok.TokenName == Lexer.Tokens.Import)
                {
                    //  Program.imports.Add( ParseImport() );
                }

                else if (tok.TokenName == Lexer.Tokens.Function)
                {
                    Block block = currentBlock;
                    if (blockstack.Count > 0 && block is Func)
                    {
                        currentBlock = blockstack.Pop();
                        currentBlock.AddStmt(block);
                    }

                    Func func = ParseFunc();

                    if (currentBlock != null)
                    {
                        blockstack.Push(currentBlock);
                        currentBlock = func;
                    }
                }
                else if (tok.TokenName == Lexer.Tokens.If)
                {
                    IfBlock ifblock = ParseIf();

                    if (currentBlock != null)
                    {
                        blockstack.Push(currentBlock);
                        currentBlock = ifblock;
                    }
                }

                /* else if ( tok.TokenName == Lexer.Tokens.ElseIf )
                 * {
                 *   ElseIfBlock elseifblock = ParseElseIf();
                 *
                 *   if ( currentBlock != null )
                 *   {
                 *       blockstack.Push( currentBlock );
                 *       currentBlock = elseifblock;
                 *   }
                 * }*/
                else if (tok.TokenName == Lexer.Tokens.Else)
                {
                    if (currentBlock != null)
                    {
                        blockstack.Push(currentBlock);
                        currentBlock = new ElseBlock()
                        {
                            Line = tok.Line
                        };
                    }
                }
                else if (tok.TokenName == Lexer.Tokens.Repeat)
                {
                    if (currentBlock != null)
                    {
                        blockstack.Push(currentBlock);
                        currentBlock = new RepeatBlock()
                        {
                            Line = tok.Line
                        };
                    }
                }
                else if (tok.TokenName == Lexer.Tokens.Set)
                {
                    Assign a = ParseAssign();
                    currentBlock.AddStmt(a);
                }

                /*else if ( tok.TokenName == Lexer.Tokens.Ident )
                 * {
                 *  if ( tokens.Peek().TokenName == Lexer.Tokens.Equal )
                 *  {
                 *      tokens.pos--;
                 *      Assign a = ParseAssign();
                 *      currentBlock.AddStmt( a );
                 *  }
                 *  else if ( tokens.Peek().TokenName == Lexer.Tokens.LeftParan )
                 *  {
                 *      tokens.pos--;
                 *      Call c = ParseCall();
                 *      currentBlock.AddStmt( c );
                 *  }
                 * }*/
                else if (tok.TokenName == Lexer.Tokens.Return)
                {
                    Return r = ParseReturn();
                    currentBlock.AddStmt(r);
                    Block block = currentBlock;

                    if (blockstack.Count > 0 && block is Func)
                    {
                        currentBlock = blockstack.Pop();
                        currentBlock.AddStmt(block);
                    }
                }
                else if (tok.TokenName == Lexer.Tokens.RightBrace)
                {
                    if (currentBlock is Func)
                    {
                        currentBlock.AddStmt(new Return(null));
                        //tree.Add( currentBlock );
                        //currentBlock = null;
                        Block block = currentBlock;

                        if (blockstack.Count > 0)
                        {
                            currentBlock = blockstack.Pop();
                            currentBlock.AddStmt(block);
                        }
                    }
                    else if (currentBlock is IfBlock || currentBlock is ElseIfBlock || currentBlock is ElseBlock)
                    {
                        currentBlock.AddStmt(new EndIf());
                        Block block = currentBlock;

                        if (blockstack.Count > 0)
                        {
                            currentBlock = blockstack.Pop();
                            currentBlock.AddStmt(block);
                        }
                    }
                    else if (currentBlock is RepeatBlock)
                    {
                        Block block = currentBlock;

                        if (blockstack.Count > 0)
                        {
                            currentBlock = blockstack.Pop();
                            currentBlock.AddStmt(block);
                        }
                    }
                }
                else if (tok.TokenName == Lexer.Tokens.EOF)
                {
                    if (currentBlock is Func)
                    {
                        currentBlock.AddStmt(new Return(null));
                        //tree.Add( currentBlock );
                        //currentBlock = null;
                        Block block = currentBlock;

                        if (blockstack.Count > 0)
                        {
                            currentBlock = blockstack.Pop();
                            currentBlock.AddStmt(block);
                        }
                    }
                    tree.Add(currentBlock);
                    running = false;
                }
            }
            return(tree);
        }
예제 #2
0
        public List <Stmt> GenerateAST()
        {
            Block currentBlock = new Block();
            var   blockstack   = new Stack <Block>();
            Token tok          = null;
            var   tree         = new List <Stmt>();
            var   running      = true;

            while (running)
            {
                try
                {
                    tok = CurrentToken;
                    CurrentIndex++;
                    if (tok == null)
                    {
                        break;
                    }
                }
                catch { }
                if (currentBlock is IfBlock ifb)
                {
                    if (BlockEndsAtThisLine != -1 && tok.Line > BlockEndsAtThisLine)
                    {
                        // currentBlock.AddStmt( new EndIf() );
                        Block block = currentBlock;

                        if (blockstack.Count > 0)
                        {
                            currentBlock = blockstack.Pop();
                            currentBlock.AddStmt(block);
                        }
                        BlockEndsAtThisLine = -1;
                    }
                }
                if (currentBlock is ForBlock || currentBlock is WhileBlock)
                {
                    if (BlockEndsAtThisLine != -1 && tok.Line > BlockEndsAtThisLine)
                    {
                        Block block = currentBlock;

                        if (blockstack.Count > 0)
                        {
                            currentBlock = blockstack.Pop();
                            currentBlock.AddStmt(block);
                        }
                        BlockEndsAtThisLine = -1;
                    }
                }

                switch (tok.TokenName)
                {
                case Lexer.Tokens.LeftBrace:
                case Lexer.Tokens.Comment:
                case Lexer.Tokens.NewLine:
                    continue;

                case Lexer.Tokens.Call:
                    currentBlock.AddStmt(ParseCall());
                    continue;

                case Lexer.Tokens.Tile:
                    currentBlock.AddStmt(ParseTile());
                    continue;

                case Lexer.Tokens.Scanjournal:
                    currentBlock.AddStmt(ParseScanJournal());
                    continue;

                case Lexer.Tokens.ExEvent:
                    currentBlock.AddStmt(ParseExEvent());
                    continue;

                case Lexer.Tokens.Target:
                    currentBlock.AddStmt(ParseTarget());
                    continue;

                case Lexer.Tokens.Msg:
                    currentBlock.AddStmt(ParseMessage());
                    continue;

                case Lexer.Tokens.Move:
                    currentBlock.AddStmt(ParseMove());
                    continue;

                case Lexer.Tokens.Menu:
                    currentBlock.AddStmt(ParseMenu());
                    continue;

                case Lexer.Tokens.Click:
                    currentBlock.AddStmt(ParseClick());
                    continue;

                case Lexer.Tokens.Pause:
                    currentBlock.AddStmt(new PauseStmt()
                    {
                        Line = tok.Line
                    });
                    continue;

                case Lexer.Tokens.Continue:
                    currentBlock.AddStmt(new Continue()
                    {
                        Line = tok.Line
                    });
                    continue;

                case Lexer.Tokens.IgnoreItem:
                    currentBlock.AddStmt(ParseIgnoreItem());
                    continue;

                case Lexer.Tokens.LinesPerCycle:
                    currentBlock.AddStmt(new LinesPerCycle(ParseExpr())
                    {
                        Line = tok.Line
                    });
                    continue;

                case Lexer.Tokens.Wait:
                    currentBlock.AddStmt(new WaitStmt(ParseExpr())
                    {
                        Line = tok.Line
                    });
                    continue;

                case Lexer.Tokens.Label:
                    currentBlock.AddStmt(new Label(tok.TokenValue.TrimEnd(new[] { ':' }).ToLowerInvariant())
                    {
                        Line = tok.Line
                    });
                    CurrentIndex++;
                    continue;

                case Lexer.Tokens.Break:
                    currentBlock.AddStmt(new Break()
                    {
                        Line = tok.Line
                    });
                    CurrentIndex++;
                    continue;

                case Lexer.Tokens.Goto:
                {
                    currentBlock.AddStmt(new Goto(CurrentToken.TokenValue.TrimEnd(new[] { ':' }).ToLowerInvariant())
                        {
                            Line = tok.Line
                        });
                    CurrentIndex++;

                    Block block = currentBlock;

                    /* if ( blockstack.Count > 0 && block is Func )
                     * {
                     *   currentBlock = blockstack.Pop();
                     *   currentBlock.AddStmt( block );
                     * }*/
                }
                    continue;

                case Lexer.Tokens.Event:
                    currentBlock.AddStmt(ParseEvent());
                    continue;

                case Lexer.Tokens.FindItem:
                    currentBlock.AddStmt(ParseFindItem());
                    continue;
                }

                if (tok.TokenName == Lexer.Tokens.Import)
                {
                    //  Program.imports.Add( ParseImport() );
                }

                else if (tok.TokenName == Lexer.Tokens.Function)
                {
                    Block block = currentBlock;
                    if (blockstack.Count > 0 && block is Func)
                    {
                        currentBlock = blockstack.Pop();
                        currentBlock.AddStmt(block);
                    }

                    Func func = ParseFunc();

                    if (currentBlock != null)
                    {
                        blockstack.Push(currentBlock);
                        currentBlock = func;
                    }
                }
                else if (tok.TokenName == Lexer.Tokens.If)
                {
                    IfBlock ifblock = ParseIf();

                    if (currentBlock != null)
                    {
                        blockstack.Push(currentBlock);
                        currentBlock = ifblock;
                    }
                }

                /* else if ( tok.TokenName == Lexer.Tokens.ElseIf )
                 * {
                 *   ElseIfBlock elseifblock = ParseElseIf();
                 *
                 *   if ( currentBlock != null )
                 *   {
                 *       blockstack.Push( currentBlock );
                 *       currentBlock = elseifblock;
                 *   }
                 * }*/
                else if (tok.TokenName == Lexer.Tokens.Else)
                {
                    if (currentBlock != null)
                    {
                        blockstack.Push(currentBlock);
                        currentBlock = new ElseBlock()
                        {
                            Line = tok.Line
                        };
                    }
                }
                else if (tok.TokenName == Lexer.Tokens.For)
                {
                    blockstack.Push(currentBlock);
                    currentBlock = ParseFor();
                }
                else if (tok.TokenName == Lexer.Tokens.While)
                {
                    blockstack.Push(currentBlock);
                    currentBlock = ParseWhile();
                }
                else if (tok.TokenName == Lexer.Tokens.Repeat)
                {
                    if (currentBlock != null)
                    {
                        blockstack.Push(currentBlock);
                        currentBlock = new RepeatBlock()
                        {
                            Line = tok.Line
                        };
                    }
                }
                else if (tok.TokenName == Lexer.Tokens.Set)
                {
                    Assign a = ParseAssign();
                    currentBlock.AddStmt(a);
                }

                /*else if ( tok.TokenName == Lexer.Tokens.Ident )
                 * {
                 *  if ( tokens.Peek().TokenName == Lexer.Tokens.Equal )
                 *  {
                 *      tokens.pos--;
                 *      Assign a = ParseAssign();
                 *      currentBlock.AddStmt( a );
                 *  }
                 *  else if ( tokens.Peek().TokenName == Lexer.Tokens.LeftParan )
                 *  {
                 *      tokens.pos--;
                 *      Call c = ParseCall();
                 *      currentBlock.AddStmt( c );
                 *  }
                 * }*/
                else if (tok.TokenName == Lexer.Tokens.Return)
                {
                    Return r = ParseReturn();
                    currentBlock.AddStmt(r);
                    Block block = currentBlock;

                    if (blockstack.Count > 0 && block is Func)
                    {
                        currentBlock = blockstack.Pop();
                        currentBlock.AddStmt(block);
                    }
                }
                else if (tok.TokenName == Lexer.Tokens.RightBrace)
                {
                    if (currentBlock is Func)
                    {
                        currentBlock.AddStmt(new Return(null));
                        //tree.Add( currentBlock );
                        //currentBlock = null;
                        Block block = currentBlock;

                        if (blockstack.Count > 0)
                        {
                            currentBlock = blockstack.Pop();
                            currentBlock.AddStmt(block);
                        }
                    }
                    else if (currentBlock is IfBlock || currentBlock is ElseIfBlock || currentBlock is ElseBlock)
                    {
                        //currentBlock.AddStmt( new EndIf() );
                        Block block = currentBlock;

                        if (blockstack.Count > 0)
                        {
                            currentBlock = blockstack.Pop();
                            currentBlock.AddStmt(block);
                        }
                    }
                    else if (currentBlock is RepeatBlock)
                    {
                        Block block = currentBlock;

                        if (blockstack.Count > 0)
                        {
                            currentBlock = blockstack.Pop();
                            currentBlock.AddStmt(block);
                        }
                    }
                    else if (currentBlock is ForBlock || currentBlock is WhileBlock)
                    {
                        Block block = currentBlock;

                        if (blockstack.Count > 0)
                        {
                            currentBlock = blockstack.Pop();
                            currentBlock.AddStmt(block);
                        }
                    }
                }
                else if (tok.TokenName == Lexer.Tokens.EOF)
                {
                    if (currentBlock is Func)
                    {
                        currentBlock.AddStmt(new Return(null));
                        //tree.Add( currentBlock );
                        //currentBlock = null;
                        Block block = currentBlock;

                        if (blockstack.Count > 0)
                        {
                            currentBlock = blockstack.Pop();
                            currentBlock.AddStmt(block);
                        }
                    }
                    tree.Add(currentBlock);
                    running = false;
                }
                else
                {
                    Console.WriteLine($"Unhandled Token at Line: {tok.Line} " + tok.TokenName + " " + tok.TokenValue);
                }
            }
            return(tree);
        }