()
| 1406 | // comparison: expr (comp_op expr)* |
| 1407 | // comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' |
| 1408 | private _parseComparison(): ExpressionNode { |
| 1409 | let leftExpr = this._parseBitwiseOrExpression(); |
| 1410 | if (leftExpr instanceof ErrorExpressionNode) { |
| 1411 | return leftExpr; |
| 1412 | } |
| 1413 | |
| 1414 | let comparisonOperator: OperatorType | undefined; |
| 1415 | |
| 1416 | if (Tokenizer.isOperatorComparison(this._peekOperatorType())) { |
| 1417 | comparisonOperator = this._peekOperatorType(); |
| 1418 | this._getNextToken(); |
| 1419 | } else if (this._consumeTokenIfKeyword(KeywordType.In)) { |
| 1420 | comparisonOperator = OperatorType.In; |
| 1421 | } else if (this._consumeTokenIfKeyword(KeywordType.Is)) { |
| 1422 | if (this._consumeTokenIfKeyword(KeywordType.Not)) { |
| 1423 | comparisonOperator = OperatorType.IsNot; |
| 1424 | } else { |
| 1425 | comparisonOperator = OperatorType.Is; |
| 1426 | } |
| 1427 | } else if (this._peekKeywordType() === KeywordType.Not) { |
| 1428 | let tokenAfterNot = this._peekToken(1); |
| 1429 | if (tokenAfterNot.type === TokenType.Keyword && |
| 1430 | (tokenAfterNot as KeywordToken).keywordType === KeywordType.In) { |
| 1431 | this._getNextToken(); |
| 1432 | this._getNextToken(); |
| 1433 | comparisonOperator = OperatorType.NotIn; |
| 1434 | } |
| 1435 | } |
| 1436 | |
| 1437 | if (comparisonOperator !== undefined) { |
| 1438 | let rightExpr = this._parseComparison(); |
| 1439 | return new BinaryExpressionNode(leftExpr, rightExpr, comparisonOperator); |
| 1440 | } |
| 1441 | |
| 1442 | return leftExpr; |
| 1443 | } |
| 1444 | |
| 1445 | // expr: xor_expr ('|' xor_expr)* |
| 1446 | private _parseBitwiseOrExpression(): ExpressionNode { |
no test coverage detected