precedence_test.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include "parser/precedence.h"
  5. #include "gmock/gmock.h"
  6. #include "gtest/gtest.h"
  7. #include "lexer/token_kind.h"
  8. namespace Carbon {
  9. namespace {
  10. using ::testing::Eq;
  11. using ::testing::Ne;
  12. TEST(PrecedenceTest, OperatorsAreRecognized) {
  13. EXPECT_TRUE(PrecedenceGroup::ForLeading(TokenKind::Minus()).hasValue());
  14. EXPECT_TRUE(PrecedenceGroup::ForLeading(TokenKind::Tilde()).hasValue());
  15. EXPECT_FALSE(PrecedenceGroup::ForLeading(TokenKind::Slash()).hasValue());
  16. EXPECT_FALSE(PrecedenceGroup::ForLeading(TokenKind::Identifier()).hasValue());
  17. EXPECT_TRUE(PrecedenceGroup::ForTrailing(TokenKind::Minus()).hasValue());
  18. EXPECT_FALSE(PrecedenceGroup::ForTrailing(TokenKind::Tilde()).hasValue());
  19. EXPECT_TRUE(PrecedenceGroup::ForTrailing(TokenKind::Slash()).hasValue());
  20. EXPECT_FALSE(
  21. PrecedenceGroup::ForTrailing(TokenKind::Identifier()).hasValue());
  22. EXPECT_TRUE(PrecedenceGroup::ForTrailing(TokenKind::Minus())->is_binary);
  23. EXPECT_FALSE(
  24. PrecedenceGroup::ForTrailing(TokenKind::MinusMinus())->is_binary);
  25. }
  26. TEST(PrecedenceTest, Associativity) {
  27. EXPECT_THAT(
  28. PrecedenceGroup::ForLeading(TokenKind::Minus())->GetAssociativity(),
  29. Eq(Associativity::RightToLeft));
  30. EXPECT_THAT(PrecedenceGroup::ForTrailing(TokenKind::PlusPlus())
  31. ->level.GetAssociativity(),
  32. Eq(Associativity::LeftToRight));
  33. EXPECT_THAT(
  34. PrecedenceGroup::ForTrailing(TokenKind::Plus())->level.GetAssociativity(),
  35. Eq(Associativity::LeftToRight));
  36. EXPECT_THAT(PrecedenceGroup::ForTrailing(TokenKind::Equal())
  37. ->level.GetAssociativity(),
  38. Eq(Associativity::RightToLeft));
  39. EXPECT_THAT(PrecedenceGroup::ForTrailing(TokenKind::PlusEqual())
  40. ->level.GetAssociativity(),
  41. Eq(Associativity::None));
  42. }
  43. TEST(PrecedenceTest, DirectRelations) {
  44. EXPECT_THAT(PrecedenceGroup::GetPriority(
  45. PrecedenceGroup::ForTrailing(TokenKind::Star())->level,
  46. PrecedenceGroup::ForTrailing(TokenKind::Plus())->level),
  47. Eq(OperatorPriority::LeftFirst));
  48. EXPECT_THAT(PrecedenceGroup::GetPriority(
  49. PrecedenceGroup::ForTrailing(TokenKind::Plus())->level,
  50. PrecedenceGroup::ForTrailing(TokenKind::Star())->level),
  51. Eq(OperatorPriority::RightFirst));
  52. EXPECT_THAT(PrecedenceGroup::GetPriority(
  53. PrecedenceGroup::ForTrailing(TokenKind::Amp())->level,
  54. PrecedenceGroup::ForTrailing(TokenKind::Less())->level),
  55. Eq(OperatorPriority::LeftFirst));
  56. EXPECT_THAT(PrecedenceGroup::GetPriority(
  57. PrecedenceGroup::ForTrailing(TokenKind::Less())->level,
  58. PrecedenceGroup::ForTrailing(TokenKind::Amp())->level),
  59. Eq(OperatorPriority::RightFirst));
  60. }
  61. TEST(PrecedenceTest, IndirectRelations) {
  62. EXPECT_THAT(PrecedenceGroup::GetPriority(
  63. PrecedenceGroup::ForTrailing(TokenKind::Star())->level,
  64. PrecedenceGroup::ForTrailing(TokenKind::OrKeyword())->level),
  65. Eq(OperatorPriority::LeftFirst));
  66. EXPECT_THAT(PrecedenceGroup::GetPriority(
  67. PrecedenceGroup::ForTrailing(TokenKind::OrKeyword())->level,
  68. PrecedenceGroup::ForTrailing(TokenKind::Star())->level),
  69. Eq(OperatorPriority::RightFirst));
  70. EXPECT_THAT(PrecedenceGroup::GetPriority(
  71. *PrecedenceGroup::ForLeading(TokenKind::Tilde()),
  72. PrecedenceGroup::ForTrailing(TokenKind::Equal())->level),
  73. Eq(OperatorPriority::LeftFirst));
  74. EXPECT_THAT(PrecedenceGroup::GetPriority(
  75. PrecedenceGroup::ForTrailing(TokenKind::Equal())->level,
  76. *PrecedenceGroup::ForLeading(TokenKind::Tilde())),
  77. Eq(OperatorPriority::RightFirst));
  78. }
  79. TEST(PrecedenceTest, IncomparableOperators) {
  80. EXPECT_THAT(PrecedenceGroup::GetPriority(
  81. *PrecedenceGroup::ForLeading(TokenKind::Tilde()),
  82. *PrecedenceGroup::ForLeading(TokenKind::NotKeyword())),
  83. Eq(OperatorPriority::Ambiguous));
  84. EXPECT_THAT(PrecedenceGroup::GetPriority(
  85. *PrecedenceGroup::ForLeading(TokenKind::Tilde()),
  86. *PrecedenceGroup::ForLeading(TokenKind::Minus())),
  87. Eq(OperatorPriority::Ambiguous));
  88. EXPECT_THAT(PrecedenceGroup::GetPriority(
  89. *PrecedenceGroup::ForLeading(TokenKind::Minus()),
  90. PrecedenceGroup::ForTrailing(TokenKind::Amp())->level),
  91. Eq(OperatorPriority::Ambiguous));
  92. EXPECT_THAT(PrecedenceGroup::GetPriority(
  93. PrecedenceGroup::ForTrailing(TokenKind::Equal())->level,
  94. PrecedenceGroup::ForTrailing(TokenKind::PipeEqual())->level),
  95. Eq(OperatorPriority::Ambiguous));
  96. EXPECT_THAT(PrecedenceGroup::GetPriority(
  97. PrecedenceGroup::ForTrailing(TokenKind::Plus())->level,
  98. PrecedenceGroup::ForTrailing(TokenKind::Amp())->level),
  99. Eq(OperatorPriority::Ambiguous));
  100. }
  101. } // namespace
  102. } // namespace Carbon