Coverage Report

Created: 2024-01-17 10:31

/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