@@ -323,6 +323,14 @@ class Parser {
323
323
// Exprs
324
324
325
325
FailureOr<ast::Expr *> parseExpr ();
326
+ FailureOr<ast::Expr *> parseLogicalOrExpr ();
327
+ FailureOr<ast::Expr *> parseLogicalAndExpr ();
328
+ FailureOr<ast::Expr *> parseEqualityExpr ();
329
+ FailureOr<ast::Expr *> parseRelationExpr ();
330
+ FailureOr<ast::Expr *> parseAddSubExpr ();
331
+ FailureOr<ast::Expr *> parseMulDivExpr ();
332
+ FailureOr<ast::Expr *> parseLogicalNotExpr ();
333
+ FailureOr<ast::Expr *> parseOtherExpr ();
326
334
327
335
// / Identifier expressions.
328
336
FailureOr<ast::Expr *> parseArrayAttrExpr ();
@@ -1871,7 +1879,53 @@ FailureOr<ast::ConstraintRef> Parser::parseArgOrResultConstraint() {
1871
1879
// ===----------------------------------------------------------------------===//
1872
1880
// Exprs
1873
1881
1874
- FailureOr<ast::Expr *> Parser::parseExpr () {
1882
+ // Operator precedence follows C++:
1883
+ // When parsing an expression, an operator which is listed on some rows below
1884
+ // with a precedence will be bound tighter (as if by parentheses) to its
1885
+ // arguments than any operator that is listed on a row further below it with a
1886
+ // lower precedence. Operators that have the same precedence are bound to their
1887
+ // arguments left-to-right. Highest precedence first:
1888
+ // - call, member access
1889
+ // - logical not
1890
+ // - multipication, division, remainder
1891
+ // - addition, subtraction
1892
+ // - relation operators
1893
+ // - equality operators
1894
+ // - logical and
1895
+ // - logical or
1896
+ FailureOr<ast::Expr *> Parser::parseExpr () { return parseLogicalOrExpr (); }
1897
+
1898
+ FailureOr<ast::Expr *> Parser::parseLogicalOrExpr () {
1899
+ return parseLogicalAndExpr ();
1900
+ }
1901
+
1902
+ FailureOr<ast::Expr *> Parser::parseLogicalAndExpr () {
1903
+ return parseEqualityExpr ();
1904
+ }
1905
+
1906
+ FailureOr<ast::Expr *> Parser::parseEqualityExpr () {
1907
+ return parseRelationExpr ();
1908
+ }
1909
+
1910
+ FailureOr<ast::Expr *> Parser::parseRelationExpr () { return parseAddSubExpr (); }
1911
+
1912
+ FailureOr<ast::Expr *> Parser::parseAddSubExpr () { return parseMulDivExpr (); }
1913
+
1914
+ FailureOr<ast::Expr *> Parser::parseMulDivExpr () {
1915
+ return parseLogicalNotExpr ();
1916
+ }
1917
+
1918
+ FailureOr<ast::Expr *> Parser::parseLogicalNotExpr () {
1919
+ switch (curToken.getKind ()) {
1920
+ case Token::kw_not:
1921
+ return parseNegatedExpr ();
1922
+ break ;
1923
+ default :
1924
+ return parseOtherExpr ();
1925
+ }
1926
+ }
1927
+
1928
+ FailureOr<ast::Expr *> Parser::parseOtherExpr () {
1875
1929
if (curToken.is (Token::underscore))
1876
1930
return parseUnderscoreExpr ();
1877
1931
@@ -1884,9 +1938,6 @@ FailureOr<ast::Expr *> Parser::parseExpr() {
1884
1938
case Token::kw_Constraint:
1885
1939
lhsExpr = parseInlineConstraintLambdaExpr ();
1886
1940
break ;
1887
- case Token::kw_not:
1888
- lhsExpr = parseNegatedExpr ();
1889
- break ;
1890
1941
case Token::identifier:
1891
1942
lhsExpr = parseIdentifierExpr ();
1892
1943
break ;
@@ -2155,6 +2206,8 @@ FailureOr<ast::Expr *> Parser::parseNegatedExpr() {
2155
2206
FailureOr<ast::Expr *> identifierExpr = parseIdentifierExpr ();
2156
2207
if (failed (identifierExpr))
2157
2208
return failure ();
2209
+ if (!curToken.is (Token::l_paren))
2210
+ return emitError (" expected `(` after function name" );
2158
2211
return parseCallExpr (*identifierExpr, /* isNegated = */ true );
2159
2212
}
2160
2213
0 commit comments