今天终于可以把 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
了.
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();
}
/// 把比较表达式分析成树结构
/// </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();
}