小鬼之家

流浪,游走于文明与原始之间. 关注底层技术,实现美好生活。

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
    今天终于可以把 if(a==1&&(c==2||a==3) && (a>3 || b<4) || (w>5 && w<10 && (u>100 || u!=50))) 语句解析成

Or
    And
        And
            EqualEqual
                Ident
                IntLiteral
            Or
                EqualEqual
                    Ident
                    IntLiteral
                EqualEqual
                    Ident
                    IntLiteral
        Or
            Greater
                Ident
                IntLiteral
            Less
                Ident
                IntLiteral
    And
        And
            Greater
                Ident
                IntLiteral
            Less
                Ident
                IntLiteral
        Or
            Greater
                Ident
                IntLiteral
            NotEqual
                Ident
                IntLiteral

了.


/// <summary>
        
/// 把比较表达式分析成树结构
        
/// </summary>
        
/// <returns></returns>

        private ExpressionNode<ExpressionStatement> ParseExpression()
        
{
            Stack
<Stack<ExpressionNode<ExpressionStatement>>> stacks = new Stack<Stack<ExpressionNode<ExpressionStatement>>>();
            Stack
<ExpressionNode<ExpressionStatement>> nodes = new Stack<ExpressionNode<ExpressionStatement>>();
            
int m = 1;
            
int basePrecedence = 0;

            
while (!_curToken.Equals(_eof))
            
{
                
switch (_curToken.TokenId)
                
{
                    
case TokenId.Ident:
                    
case TokenId.SIdent:
                    
case TokenId.IntLiteral:
                    
case TokenId.RealLiteral:
                    
case TokenId.TrueLiteral:
                    
case TokenId.UIntLiteral:
                    
case TokenId.String:
                    
case TokenId.FString:
                    
case TokenId.StringLiteral:
                    
case TokenId.NullLiteral:
                    
case TokenId.LongLiteral:
                    
case TokenId.HexLiteral:
                    
case TokenId.FalseLiteral:
                    
case TokenId.DecimalLiteral:
                    
case TokenId.CharLiteral:
                    
case TokenId.ULongLiteral:
                        
{
                            ExpressionStatement exp 
= new ExpressionStatement(_curToken);
                            ExpressionNode
<ExpressionStatement> newNode = new ExpressionNode<ExpressionStatement>(exp);
                            
if (nodes.Count.Equals(0))
                            
{
                                nodes.Push(newNode);
                            }

                            
else if (nodes.Peek().Precedence < (GetPrecedence(NextToken().TokenId) + basePrecedence))
                            
{
                                nodes.Push(newNode);
                            }

                            
else
                            
{
                                nodes.Peek().AddRightNode(newNode);

                                
if (nodes.Count >= 2)
                                
{
                                    ExpressionNode
<ExpressionStatement> first;

                                    
while (nodes.Count >= 2)
                                    
{
                                        first 
= nodes.Pop();
                                        nodes.Peek().AddRightNode(first);
                                    }

                                }


                            }

                            Advance();
                            
break;
                        }

                    
case TokenId.EqualEqual:
                    
case TokenId.Greater:
                    
case TokenId.GreaterEqual:
                    
case TokenId.Less:
                    
case TokenId.LessEqual:
                    
case TokenId.NotEqual:
                        
{
                            
// == > >= < <= !=
                            ExpressionStatement exp = new ExpressionStatement(_curToken);
                            ExpressionNode
<ExpressionStatement> newNode = new ExpressionNode<ExpressionStatement>(exp, GenPrecedence(m));
                            newNode.AddLeftNode(nodes.Pop());
                            nodes.Push(newNode);
                            Advance();
                            
break;
                        }

                    
case TokenId.And:
                        
{
                            
// &&
                            ExpressionStatement exp = new ExpressionStatement(_curToken);
                            ExpressionNode
<ExpressionStatement> newNode = new ExpressionNode<ExpressionStatement>(exp, GenPrecedence(m));
                            newNode.AddLeftNode(nodes.Pop());
                            nodes.Push(newNode);
                            Advance();
                            
break;
                        }

                    
case TokenId.Or:
                        
{
                            
// ||
                            ExpressionStatement exp = new ExpressionStatement(_curToken);
                            ExpressionNode
<ExpressionStatement> newNode = new ExpressionNode<ExpressionStatement>(exp, GenPrecedence(m));
                            newNode.AddLeftNode(nodes.Pop());
                            nodes.Push(newNode);
                            Advance();
                            
break;
                        }

                    
case TokenId.Not:
                        
{
                            
// !
                            ExpressionStatement exp = new ExpressionStatement(_curToken);
                            ExpressionNode
<ExpressionStatement> newNode = new ExpressionNode<ExpressionStatement>(exp, GenPrecedence(m));
                            nodes.Push(newNode);
                            Advance();
                            
break;
                        }

                    
case TokenId.Plus:
                    
case TokenId.PlusEqual:
                    
case TokenId.Minus:
                    
case TokenId.MinusEqual:
                        
{
                            
// + += - -=
                            ExpressionStatement exp = new ExpressionStatement(_curToken);
                            ExpressionNode
<ExpressionStatement> newNode = new ExpressionNode<ExpressionStatement>(exp, GenPrecedence(m));
                            newNode.AddLeftNode(nodes.Pop());
                            nodes.Push(newNode);
                            Advance();
                            
break;
                        }

                    
case TokenId.Star:
                    
case TokenId.StarEqual:
                    
case TokenId.Slash:
                    
case TokenId.SlashEqual:
                    
case TokenId.Percent:
                    
case TokenId.PercentEqual:
                        
{
                            
// * *= / /= % %=
                            ExpressionStatement exp = new ExpressionStatement(_curToken);
                            ExpressionNode
<ExpressionStatement> newNode = new ExpressionNode<ExpressionStatement>(exp, GenPrecedence(m));
                            newNode.AddLeftNode(nodes.Pop());
                            nodes.Push(newNode);

                            Advance();
                            
break;
                        }

                    
case TokenId.LParen:
                        
{
                            m
++;
                            basePrecedence 
+= 10;
                            stacks.Push(nodes);
                            nodes 
= new Stack<ExpressionNode<ExpressionStatement>>();
                            Advance();
                            
break;
                        }

                    
case TokenId.RParen:
                        
{
                            m
--;
                            basePrecedence 
-= 10;

                            
if (m > 0)
                            
{
                                
while (stacks.Count > 0)
                                
{
                                    ExpressionNode
<ExpressionStatement> first = nodes.Pop();
                                    nodes 
= stacks.Pop();
                                    nodes.Peek().AddRightNode(first);
                                }

                                Advance();
                            }

                            
break;
                        }

                    
default:
                        
{
                            Advance();
                            
break;
                        }

                }


                
if (m.Equals(0))
                
{
                    
break;
                }

            }


            
return nodes.Pop();
        }
posted on 2008-04-18 16:47  黄尚  阅读(316)  评论(0编辑  收藏  举报