10#include <unordered_map>
11#include <unordered_set>
20struct LineAndColumnTracker {
22 LineAndColumn current{0, 0, 0};
26 current.offset += std::distance(from, to);
38 SourcePosition ToSourcePosition() {
39 return {CurrentSourceFile::Get(),
previous, current};
47 std::vector<ParseResult> results;
50 std::optional<ParseResult> child_result =
51 child->left()->RunAction(child, tokens);
52 if (child_result) results.push_back(std::move(*child_result));
55 CurrentSourcePosition::Scope pos_scope(matched_input.
pos);
73 for (
const Item* current =
this; current->
prev_; current = current->prev_) {
85 return child->SplitByChildren(tokens);
92 s << item->GetMatchedInput(tokens).ToString();
100 if (
child_ != other.child_) {
102 s <<
"Ambiguous grammer rules for \""
103 <<
child_->GetMatchedInput(tokens).ToString() <<
"\":\n "
104 <<
child_->SplitByChildren(tokens) <<
"\nvs\n "
105 << other.child_->SplitByChildren(tokens);
108 if (
prev_ != other.prev_) {
112 << other.SplitByChildren(tokens) <<
" ...";
123 LineAndColumnTracker line_column_tracker;
126 line_column_tracker.Advance(token_start,
pos);
132 line_column_tracker.Advance(token_start, token_end);
134 CurrentSourcePosition::Scope pos_scope(
135 line_column_tracker.ToSourcePosition());
138 token_start, token_start + std::min<ptrdiff_t>(
139 end - token_start, 10))));
141 result.token_symbols.push_back(symbol);
142 result.token_contents.push_back(
143 {token_start,
pos, line_column_tracker.ToSourcePosition()});
145 line_column_tracker.Advance(token_end,
pos);
149 line_column_tracker.Advance(token_start,
pos);
150 result.token_contents.push_back(
151 {
pos,
pos, line_column_tracker.ToSourcePosition()});
159 for (std::pair<const PatternFunction, Symbol>& pair :
patterns_) {
162 if (matchPattern(&token_end) && token_end > *
pos) {
164 symbol = &pair.second;
167 size_t pattern_size = *
pos - token_start;
173 const std::string& keyword = it->first;
174 if (
static_cast<size_t>(
end - token_start) < keyword.size())
continue;
175 if (keyword.size() >= pattern_size &&
176 keyword == std::string(token_start, token_start + keyword.size())) {
177 *
pos = token_start + keyword.size();
181 if (pattern_size > 0)
return symbol;
191 std::vector<Item> worklist;
193 std::vector<Item> future_items;
194 CurrentSourcePosition::Scope source_position(
197 std::vector<const Item*> completed_items;
198 std::unordered_map<std::pair<size_t, Symbol*>, std::set<const Item*>,
202 std::vector<const Item*> debug_trace;
209 worklist.push_back(
Item{top_level.
rule(0), 0, 0, 0});
213 for (
size_t pos = 0;
pos <= input_length; ++
pos) {
214 while (!worklist.empty()) {
215 auto insert_result = processed->insert(worklist.back());
216 const Item& item = *insert_result.first;
219 CurrentSourcePosition::Get() = last_token.
pos;
220 bool is_new = insert_result.second;
223 if (!is_new)
continue;
225 debug_trace.push_back(&item);
229 for (
const Item* parent : waiting[{item.
start(), item.
left()}]) {
230 worklist.push_back(parent->Advance(
pos, &item));
238 future_items.push_back(item.
Advance(
pos + 1,
nullptr));
243 waiting[{
pos, next}].insert(&item);
247 auto already_completed =
257 if (already_completed != processed->end()) {
258 worklist.push_back(item.
Advance(
pos, &*already_completed));
265 std::swap(worklist, future_items);
269 processed->find(
Item{top_level.
rule(0), 1, 0, input_length});
270 if (final_item != processed->end()) {
272 return final_item->Children()[0];
275 const Item& last_item = *debug_trace.back();
278 reason =
"unexpected token \"" + next_token +
"\"";
280 reason =
"unexpected end of input";
288 if (**
pos && char_class(
static_cast<unsigned char>(**
pos))) {
297 if (**
pos && char_class(**
pos)) {
308 if (*s != *current)
return false;
static V8_EXPORT_PRIVATE bool MatchAnyChar(InputPosition *pos)
static V8_EXPORT_PRIVATE bool MatchString(const char *s, InputPosition *pos)
static V8_EXPORT_PRIVATE bool MatchChar(int(*char_class)(int), InputPosition *pos)
std::string SplitByChildren(const LexerResult &tokens) const
Symbol * NextSymbol() const
Item Advance(size_t new_pos, const Item *child=nullptr) const
const std::vector< Symbol * > & right() const
void CheckAmbiguity(const Item &other, const LexerResult &tokens) const
std::vector< const Item * > Children() const
MatchedInput GetMatchedInput(const LexerResult &tokens) const
bool(*)(InputPosition *pos) PatternFunction
Symbol * MatchToken(InputPosition *pos, InputPosition end)
std::map< PatternFunction, Symbol > patterns_
V8_EXPORT_PRIVATE LexerResult RunLexer(const std::string &input)
PatternFunction match_whitespace_
std::map< std::string, Symbol > keywords_
V8_EXPORT_PRIVATE std::optional< ParseResult > RunAction(const Item *completed_item, const LexerResult &tokens) const
const std::vector< Symbol * > & right() const
Symbol & operator=(const Symbol &)=delete
Rule * rule(size_t index) const
size_t rule_number() const
std::vector< std::unique_ptr< Rule > > rules_
void AddRule(const Rule &rule)
std::vector< std::unique_ptr< InstanceTypeTree > > children
ZoneVector< RpoNumber > & result
std::string StringLiteralQuote(const std::string &s)
void ReportError(Args &&... args)
const char * InputPosition
const Item * RunEarleyAlgorithm(Symbol *start, const LexerResult &tokens, std::unordered_set< Item, base::hash< Item > > *processed)
#define DCHECK_IMPLIES(v1, v2)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
#define DISABLE_CFI_ICALL
std::vector< MatchedInput > token_contents
std::vector< Symbol * > token_symbols
static LineAndColumn Invalid()