5 #ifndef V8_TORQUE_EARLEY_PARSER_H_ 6 #define V8_TORQUE_EARLEY_PARSER_H_ 11 #include "src/base/optional.h" 12 #include "src/torque/contextual.h" 13 #include "src/torque/source-positions.h" 14 #include "src/torque/utils.h" 30 const T& Cast()
const;
39 const TypeId type_id_;
42 using ParseResultTypeId = ParseResultHolderBase::TypeId;
51 V8_EXPORT_PRIVATE
static const TypeId id;
57 T& ParseResultHolderBase::Cast() {
63 const T& ParseResultHolderBase::Cast()
const {
64 CHECK_EQ(ParseResultHolder<T>::id, type_id_);
65 return static_cast<const ParseResultHolder<T>*
>(
this)->value_;
74 const T& Cast()
const {
75 return value_->Cast<
T>();
79 return value_->Cast<
T>();
83 std::unique_ptr<ParseResultHolderBase> value_;
90 : begin(begin), end(end), pos(pos) {}
94 std::string
ToString()
const {
return {begin, end}; }
101 : results_(std::move(results)), matched_input_(matched_input) {}
104 CHECK_EQ(results_.size(), i_);
108 CHECK_LT(i_, results_.size());
109 return std::move(results_[i_++]);
113 return std::move(Next().Cast<T>());
115 bool HasNext()
const {
return i_ < results_.size(); }
117 const MatchedInput& matched_input()
const {
return matched_input_; }
120 std::vector<ParseResult> results_;
128 std::vector<Symbol*> token_symbols;
129 std::vector<MatchedInput> token_contents;
137 if (!child_results->HasNext())
return base::nullopt;
138 return child_results->Next();
145 explicit Rule(std::vector<Symbol*> right_hand_side,
146 Action action = DefaultAction)
147 : right_hand_side_(std::move(right_hand_side)), action_(action) {}
150 DCHECK_NOT_NULL(left_hand_side_);
151 return left_hand_side_;
153 const std::vector<Symbol*>& right()
const {
return right_hand_side_; }
155 void SetLeftHandSide(
Symbol* left_hand_side) {
156 DCHECK_NULL(left_hand_side_);
157 left_hand_side_ = left_hand_side;
164 Symbol* left_hand_side_ =
nullptr;
165 std::vector<Symbol*> right_hand_side_;
179 Symbol(std::initializer_list<Rule> rules) { *
this = rules; }
181 V8_EXPORT_PRIVATE
Symbol& operator=(std::initializer_list<Rule> rules);
183 bool IsTerminal()
const {
return rules_.empty(); }
184 Rule* rule(
size_t index)
const {
return rules_[index].get(); }
185 size_t rule_number()
const {
return rules_.size(); }
187 void AddRule(
const Rule& rule) {
188 rules_.push_back(base::make_unique<Rule>(rule));
189 rules_.back()->SetLeftHandSide(
this);
196 std::vector<std::unique_ptr<Rule>> rules_;
199 DISALLOW_COPY_AND_MOVE_AND_ASSIGN(
Symbol);
210 Item(
const Rule* rule,
size_t mark,
size_t start,
size_t pos)
211 : rule_(rule), mark_(mark), start_(start), pos_(pos) {
212 DCHECK_LE(mark_, right().size());
217 bool IsComplete()
const {
218 DCHECK_LE(mark_, right().size());
219 return mark_ == right().size();
224 Symbol* NextSymbol()
const {
225 DCHECK(!IsComplete());
226 DCHECK_LT(mark_, right().size());
227 return right()[mark_];
234 Item Advance(
size_t new_pos,
const Item* child =
nullptr)
const {
236 DCHECK(child->IsComplete());
237 DCHECK_EQ(pos(), child->start());
238 DCHECK_EQ(new_pos, child->pos());
239 DCHECK_EQ(NextSymbol(), child->left());
241 Item result(rule_, mark_ + 1, start_, new_pos);
243 result.child_ = child;
248 std::vector<const Item*> Children()
const;
250 std::string SplitByChildren(
const LexerResult& tokens)
const;
252 void CheckAmbiguity(
const Item& other,
const LexerResult& tokens)
const;
255 return {tokens.token_contents[start_].begin,
256 start_ == pos_ ? tokens.token_contents[start_].begin
257 : tokens.token_contents[pos_ - 1].end,
258 tokens.token_contents[start_].pos};
263 bool operator==(
const Item& other)
const {
264 return rule_ == other.rule_ && mark_ == other.mark_ &&
265 start_ == other.start_ && pos_ == other.pos_;
268 friend size_t hash_value(
const Item&
i) {
269 return base::hash_combine(
i.rule_,
i.mark_,
i.start_,
i.pos_);
272 const Rule* rule()
const {
return rule_; }
273 Symbol* left()
const {
return rule_->left(); }
274 const std::vector<Symbol*>& right()
const {
return rule_->right(); }
275 size_t pos()
const {
return pos_; }
276 size_t start()
const {
return start_; }
284 const Item* prev_ =
nullptr;
285 const Item* child_ =
nullptr;
290 DCHECK(item->IsComplete());
291 DCHECK_EQ(item->left(),
this);
292 return item->rule()->RunAction(item, tokens);
295 V8_EXPORT_PRIVATE
const Item* RunEarleyAlgorithm(
296 Symbol* start,
const LexerResult& tokens,
300 const LexerResult& tokens) {
301 std::unordered_set<Item, base::hash<Item>> table;
302 const Item* final_item = RunEarleyAlgorithm(start, tokens, &table);
303 return start->RunAction(final_item, tokens);
324 void SetWhitespace(PatternFunction whitespace) {
325 match_whitespace_ = whitespace;
328 Symbol* Pattern(PatternFunction pattern) {
return &patterns_[pattern]; }
329 Symbol*
Token(
const std::string& keyword) {
return &keywords_[keyword]; }
330 V8_EXPORT_PRIVATE
LexerResult RunLexer(
const std::string& input);
333 PatternFunction match_whitespace_ = [](
InputPosition*) {
return false; };
334 std::map<PatternFunction, Symbol> patterns_;
335 std::map<std::string, Symbol> keywords_;
344 using PatternFunction = Lexer::PatternFunction;
350 return ParseTokens(start_, tokens);
354 Symbol*
Token(
const std::string& s) {
return lexer_.Token(s); }
355 Symbol* Pattern(PatternFunction pattern) {
return lexer_.Pattern(pattern); }
356 void SetWhitespace(PatternFunction ws) { lexer_.SetWhitespace(ws); }
360 Symbol* NewSymbol(std::initializer_list<Rule> rules = {}) {
362 generated_symbols_.push_back(std::unique_ptr<Symbol>(result));
368 V8_EXPORT_PRIVATE
static bool MatchChar(
int (*char_class)(
int),
370 V8_EXPORT_PRIVATE
static bool MatchChar(
bool (*char_class)(
char),
372 V8_EXPORT_PRIVATE
static bool MatchAnyChar(
InputPosition* pos);
373 V8_EXPORT_PRIVATE
static bool MatchString(
const char* s,
InputPosition* pos);
379 return ParseResult{child_results->matched_input().ToString()};
384 Symbol* Sequence(std::vector<Symbol*> symbols) {
385 return NewSymbol({
Rule(std::move(symbols))});
388 template <
class T, T value>
400 template <
class From,
class To>
403 To result = std::move(child_results->NextAs<From>());
409 template <
class T,
class Result = T>
411 return NewSymbol({
Rule({s}, CastParseResult<Result, T>),
412 Rule({}, YieldDefaultValue<T>)});
418 T x = child_results->NextAs<
T>();
419 std::vector<T> result;
420 result.push_back(std::move(x));
427 std::vector<T> l = child_results->NextAs<std::vector<T>>();
428 T x = child_results->NextAs<
T>();
429 l.push_back(std::move(x));
438 Symbol* list = NewSymbol();
439 *list = {
Rule({element}, MakeSingletonVector<T>),
441 ?
Rule({list, *separator, element}, MakeExtendedVector<T>)
442 :
Rule({list, element}, MakeExtendedVector<T>)};
448 return TryOrDefault<std::vector<T>>(NonemptyList<T>(element, separator));
453 return TryOrDefault<base::Optional<T>,
T>(x);
457 return NewSymbol({
Rule({x}, YieldIntegralConstant<bool, true>),
458 Rule({}, YieldIntegralConstant<bool, false>)});
461 Lexer& lexer() {
return lexer_; }
465 std::vector<std::unique_ptr<Symbol>> generated_symbols_;
473 #endif // V8_TORQUE_EARLEY_PARSER_H_