/src/llvm-project/clang-tools-extra/pseudo/lib/grammar/LRTable.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- LRTable.cpp - Parsing table for LR parsers --------------*- 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 "llvm/ADT/ArrayRef.h" |
12 | | #include "llvm/ADT/STLExtras.h" |
13 | | #include "llvm/ADT/StringExtras.h" |
14 | | #include "llvm/Support/FormatVariadic.h" |
15 | | #include "llvm/Support/raw_ostream.h" |
16 | | |
17 | | namespace clang { |
18 | | namespace pseudo { |
19 | | |
20 | 0 | std::string LRTable::dumpStatistics() const { |
21 | 0 | return llvm::formatv(R"( |
22 | 0 | Statistics of the LR parsing table: |
23 | 0 | number of states: {0} |
24 | 0 | number of actions: shift={1} goto={2} reduce={3} |
25 | 0 | size of the table (bytes): {4} |
26 | 0 | )", |
27 | 0 | numStates(), Shifts.size(), Gotos.size(), Reduces.size(), |
28 | 0 | bytes()) |
29 | 0 | .str(); |
30 | 0 | } |
31 | | |
32 | 0 | std::string LRTable::dumpForTests(const Grammar &G) const { |
33 | 0 | std::string Result; |
34 | 0 | llvm::raw_string_ostream OS(Result); |
35 | 0 | OS << "LRTable:\n"; |
36 | 0 | for (StateID S = 0; S < numStates(); ++S) { |
37 | 0 | OS << llvm::formatv("State {0}\n", S); |
38 | 0 | for (uint16_t Terminal = 0; Terminal < NumTerminals; ++Terminal) { |
39 | 0 | SymbolID TokID = tokenSymbol(static_cast<tok::TokenKind>(Terminal)); |
40 | 0 | if (auto SS = getShiftState(S, TokID)) |
41 | 0 | OS.indent(4) << llvm::formatv("{0}: shift state {1}\n", |
42 | 0 | G.symbolName(TokID), SS); |
43 | 0 | } |
44 | 0 | for (RuleID R : getReduceRules(S)) { |
45 | 0 | SymbolID Target = G.lookupRule(R).Target; |
46 | 0 | std::vector<llvm::StringRef> Terminals; |
47 | 0 | for (unsigned Terminal = 0; Terminal < NumTerminals; ++Terminal) { |
48 | 0 | SymbolID TokID = tokenSymbol(static_cast<tok::TokenKind>(Terminal)); |
49 | 0 | if (canFollow(Target, TokID)) |
50 | 0 | Terminals.push_back(G.symbolName(TokID)); |
51 | 0 | } |
52 | 0 | OS.indent(4) << llvm::formatv("{0}: reduce by rule {1} '{2}'\n", |
53 | 0 | llvm::join(Terminals, " "), R, |
54 | 0 | G.dumpRule(R)); |
55 | 0 | } |
56 | 0 | for (SymbolID NontermID = 0; NontermID < G.table().Nonterminals.size(); |
57 | 0 | ++NontermID) { |
58 | 0 | if (auto GS = getGoToState(S, NontermID)) { |
59 | 0 | OS.indent(4) << llvm::formatv("{0}: go to state {1}\n", |
60 | 0 | G.symbolName(NontermID), *GS); |
61 | 0 | } |
62 | 0 | } |
63 | 0 | } |
64 | 0 | return OS.str(); |
65 | 0 | } |
66 | | |
67 | 9.56k | LRTable::StateID LRTable::getStartState(SymbolID Target) const { |
68 | 9.56k | assert(llvm::is_sorted(StartStates) && "StartStates must be sorted!"); |
69 | 0 | auto It = llvm::partition_point( |
70 | 19.1k | StartStates, [Target](const std::pair<SymbolID, StateID> &X) { |
71 | 19.1k | return X.first < Target; |
72 | 19.1k | }); |
73 | 9.56k | assert(It != StartStates.end() && It->first == Target && |
74 | 9.56k | "target symbol doesn't have a start state!"); |
75 | 0 | return It->second; |
76 | 9.56k | } |
77 | | |
78 | | } // namespace pseudo |
79 | | } // namespace clang |