1//===--- LRTableTest.cpp - ---------------------------------------*- C++-*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "clang-pseudo/grammar/LRTable.h"
10#include "clang-pseudo/grammar/Grammar.h"
11#include "clang/Basic/TokenKinds.h"
12#include "llvm/Testing/Support/SupportHelpers.h"
13#include "gmock/gmock.h"
14#include "gtest/gtest.h"
15#include <vector>
16
17namespace clang {
18namespace pseudo {
19namespace {
20
21using llvm::ValueIs;
22using testing::ElementsAre;
23using StateID = LRTable::StateID;
24
25TEST(LRTable, Builder) {
26 std::vector<std::string> GrammarDiags;
27 Grammar G = Grammar::parseBNF(BNF: R"bnf(
28 _ := expr # rule 0
29 expr := term # rule 1
30 expr := expr + term # rule 2
31 term := IDENTIFIER # rule 3
32 )bnf",
33 Diags&: GrammarDiags);
34 EXPECT_THAT(GrammarDiags, testing::IsEmpty());
35
36 SymbolID Term = *G.findNonterminal(Name: "term");
37 SymbolID Eof = tokenSymbol(TK: tok::eof);
38 SymbolID Identifier = tokenSymbol(TK: tok::identifier);
39 SymbolID Plus = tokenSymbol(TK: tok::plus);
40
41 LRTable::Builder B(G);
42 // eof IDENT term
43 // +-------+----+-------+------+
44 // |state0 | | s0 | |
45 // |state1 | | | g3 |
46 // |state2 | | | |
47 // +-------+----+-------+------+-------
48 B.Transition[{StateID{0}, Identifier}] = StateID{0};
49 B.Transition[{StateID{1}, Term}] = StateID{3};
50 B.Reduce[StateID{0}].insert(V: RuleID{0});
51 B.Reduce[StateID{1}].insert(V: RuleID{2});
52 B.Reduce[StateID{2}].insert(V: RuleID{1});
53 LRTable T = std::move(B).build();
54
55 EXPECT_EQ(T.getShiftState(0, Eof), std::nullopt);
56 EXPECT_THAT(T.getShiftState(0, Identifier), ValueIs(0));
57 EXPECT_THAT(T.getReduceRules(0), ElementsAre(0));
58
59 EXPECT_EQ(T.getShiftState(1, Eof), std::nullopt);
60 EXPECT_EQ(T.getShiftState(1, Identifier), std::nullopt);
61 EXPECT_THAT(T.getGoToState(1, Term), ValueIs(3));
62 EXPECT_THAT(T.getReduceRules(1), ElementsAre(2));
63
64 // Verify the behaivor for other non-available-actions terminals.
65 SymbolID Int = tokenSymbol(TK: tok::kw_int);
66 EXPECT_EQ(T.getShiftState(2, Int), std::nullopt);
67
68 // Check follow sets.
69 EXPECT_TRUE(T.canFollow(Term, Plus));
70 EXPECT_TRUE(T.canFollow(Term, Eof));
71 EXPECT_FALSE(T.canFollow(Term, Int));
72}
73
74} // namespace
75} // namespace pseudo
76} // namespace clang
77

source code of clang-tools-extra/pseudo/unittests/LRTableTest.cpp