mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-12-03 12:03:51 +08:00
Implement parsing of relational operators
--HG-- branch : dev
This commit is contained in:
@@ -110,6 +110,100 @@ namespace Orchard.Tests.Modules.Scripting {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ParserShouldUnderstandRelationalOperators() {
|
||||||
|
var tree = new Parser("true == true").Parse();
|
||||||
|
CheckTree(tree, new object[] {
|
||||||
|
"binop", TokenKind.EqualEqual,
|
||||||
|
"const", true,
|
||||||
|
"const", true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ParserShouldUnderstandRelationalOperators2() {
|
||||||
|
var tree = new Parser("1 != 2").Parse();
|
||||||
|
CheckTree(tree, new object[] {
|
||||||
|
"binop", TokenKind.NotEqual,
|
||||||
|
"const", 1,
|
||||||
|
"const", 2,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ParserShouldUnderstandRelationalOperators3() {
|
||||||
|
var tree = new Parser("1 < 2").Parse();
|
||||||
|
CheckTree(tree, new object[] {
|
||||||
|
"binop", TokenKind.LessThan,
|
||||||
|
"const", 1,
|
||||||
|
"const", 2,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ParserShouldUnderstandRelationalOperators4() {
|
||||||
|
var tree = new Parser("1 <= 2").Parse();
|
||||||
|
CheckTree(tree, new object[] {
|
||||||
|
"binop", TokenKind.LessThanEqual,
|
||||||
|
"const", 1,
|
||||||
|
"const", 2,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ParserShouldUnderstandRelationalOperators5() {
|
||||||
|
var tree = new Parser("1 > 2").Parse();
|
||||||
|
CheckTree(tree, new object[] {
|
||||||
|
"binop", TokenKind.GreaterThan,
|
||||||
|
"const", 1,
|
||||||
|
"const", 2,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ParserShouldUnderstandRelationalOperators6() {
|
||||||
|
var tree = new Parser("1 >= 2").Parse();
|
||||||
|
CheckTree(tree, new object[] {
|
||||||
|
"binop", TokenKind.GreaterThanEqual,
|
||||||
|
"const", 1,
|
||||||
|
"const", 2,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ParserShouldUnderstandRelationalOperatorPrecedence() {
|
||||||
|
var tree = new Parser("1 < 2 or 2 > 3 and !false").Parse();
|
||||||
|
CheckTree(tree, new object[] {
|
||||||
|
"binop", TokenKind.Or,
|
||||||
|
"binop", TokenKind.LessThan,
|
||||||
|
"const", 1,
|
||||||
|
"const", 2,
|
||||||
|
"binop", TokenKind.And,
|
||||||
|
"binop", TokenKind.GreaterThan,
|
||||||
|
"const", 2,
|
||||||
|
"const", 3,
|
||||||
|
"unop", TokenKind.NotSign,
|
||||||
|
"const", false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ParserShouldUnderstandRelationalOperatorPrecedence2() {
|
||||||
|
var tree = new Parser("1 < 2 and 2 > 3 or !false").Parse();
|
||||||
|
CheckTree(tree, new object[] {
|
||||||
|
"binop", TokenKind.And,
|
||||||
|
"binop", TokenKind.LessThan,
|
||||||
|
"const", 1,
|
||||||
|
"const", 2,
|
||||||
|
"binop", TokenKind.Or,
|
||||||
|
"binop", TokenKind.GreaterThan,
|
||||||
|
"const", 2,
|
||||||
|
"const", 3,
|
||||||
|
"unop", TokenKind.NotSign,
|
||||||
|
"const", false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void ParserShouldUnderstandParenthesis() {
|
public void ParserShouldUnderstandParenthesis() {
|
||||||
var tree = new Parser("1*(2+3)").Parse();
|
var tree = new Parser("1*(2+3)").Parse();
|
||||||
@@ -177,6 +271,8 @@ namespace Orchard.Tests.Modules.Scripting {
|
|||||||
case "error":
|
case "error":
|
||||||
type = typeof(ErrorAstNode);
|
type = typeof(ErrorAstNode);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
throw new InvalidOperationException(string.Format("Test error: unrecognized expression type abbreviation '{0}'", exprName));
|
||||||
}
|
}
|
||||||
|
|
||||||
Trace.WriteLine(string.Format("{0}: {1}{2} (Current: {3})", indent, new string(' ', indent * 2), type.Name, astNode));
|
Trace.WriteLine(string.Format("{0}: {1}{2} (Current: {3})", indent, new string(' ', indent * 2), type.Name, astNode));
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace Orchard.Scripting.Ast {
|
|||||||
private readonly AstNode _operand;
|
private readonly AstNode _operand;
|
||||||
private readonly Token _token;
|
private readonly Token _token;
|
||||||
|
|
||||||
public UnaryAstNode(AstNode operand, Token token) {
|
public UnaryAstNode(Token token, AstNode operand) {
|
||||||
_operand = operand;
|
_operand = operand;
|
||||||
_token = token;
|
_token = token;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,28 +22,11 @@ namespace Orchard.Scripting.Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private AstNode ParseKeywordLogicalExpression() {
|
private AstNode ParseKeywordLogicalExpression() {
|
||||||
return ParseKeywordOrExpression();
|
|
||||||
}
|
|
||||||
|
|
||||||
private AstNode ParseKeywordOrExpression() {
|
|
||||||
var expr = ParseKeywordAndExpression();
|
|
||||||
|
|
||||||
var token = IsMatch(TokenKind.Or);
|
|
||||||
if (token != null) {
|
|
||||||
var right = ParseKeywordOrExpression();
|
|
||||||
|
|
||||||
expr = new BinaryAstNode(expr, token, right);
|
|
||||||
}
|
|
||||||
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
|
|
||||||
private AstNode ParseKeywordAndExpression() {
|
|
||||||
var expr = ParseKeywordNotExpression();
|
var expr = ParseKeywordNotExpression();
|
||||||
|
|
||||||
var token = IsMatch(TokenKind.And);
|
var token = IsMatch(TokenKind.Or, TokenKind.And);
|
||||||
if (token != null) {
|
if (token != null) {
|
||||||
var right = ParseKeywordAndExpression();
|
var right = ParseKeywordLogicalExpression();
|
||||||
|
|
||||||
expr = new BinaryAstNode(expr, token, right);
|
expr = new BinaryAstNode(expr, token, right);
|
||||||
}
|
}
|
||||||
@@ -56,15 +39,37 @@ namespace Orchard.Scripting.Compiler {
|
|||||||
if (token != null) {
|
if (token != null) {
|
||||||
var expr = ParseKeywordNotExpression();
|
var expr = ParseKeywordNotExpression();
|
||||||
|
|
||||||
return new UnaryAstNode(expr, token);
|
return new UnaryAstNode(token, expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ParseRelationalExpression();
|
return ParseEqualityExpression();
|
||||||
|
}
|
||||||
|
|
||||||
|
private AstNode ParseEqualityExpression() {
|
||||||
|
var expr = ParseRelationalExpression();
|
||||||
|
|
||||||
|
var token = IsMatch(TokenKind.EqualEqual, TokenKind.NotEqual);
|
||||||
|
if (token != null) {
|
||||||
|
var right = ParseEqualityExpression();
|
||||||
|
|
||||||
|
expr = new BinaryAstNode(expr, token, right);
|
||||||
|
}
|
||||||
|
|
||||||
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
private AstNode ParseRelationalExpression() {
|
private AstNode ParseRelationalExpression() {
|
||||||
var expr = ParseAdditiveExpression();
|
var expr = ParseAdditiveExpression();
|
||||||
//TODO
|
|
||||||
|
var token =
|
||||||
|
IsMatch(TokenKind.LessThan, TokenKind.LessThanEqual) ??
|
||||||
|
IsMatch(TokenKind.GreaterThan, TokenKind.GreaterThanEqual);
|
||||||
|
if (token != null) {
|
||||||
|
var right = ParseRelationalExpression();
|
||||||
|
|
||||||
|
expr = new BinaryAstNode(expr, token, right);
|
||||||
|
}
|
||||||
|
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,7 +100,13 @@ namespace Orchard.Scripting.Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private AstNode ParseUnaryExpression() {
|
private AstNode ParseUnaryExpression() {
|
||||||
//TODO
|
var token = IsMatch(TokenKind.NotSign);
|
||||||
|
if (token != null) {
|
||||||
|
var expr = ParseUnaryExpression();
|
||||||
|
|
||||||
|
return new UnaryAstNode(token, expr);
|
||||||
|
}
|
||||||
|
|
||||||
return ParsePrimaryExpression();
|
return ParsePrimaryExpression();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user