// Copyright 2026 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifdef V8_ENABLE_REGEXP_DIAGNOSTICS
#include "irregexp/imported/regexp-ast-printer.h"
#include "irregexp/imported/regexp-ast.h"
#include "irregexp/imported/regexp-graph-printer.h"
namespace v8 {
namespace internal {
namespace regexp {
void AstNodePrinter::VisitCharacterRange(CharacterRange that) {
os() << AsUC32(that.from());
if (!that.IsSingleton()) {
os() << "-" << AsUC32(that.to());
}
}
void * AstNodePrinter::VisitDisjunction(Disjunction* that, void * data) {
RegisterNode(that);
PrintNodeLabel(that);
os() << "(|" ;
for (int i = 0 ; i < that->alternatives()->length(); i++) {
os() << " " ;
that->alternatives()->at(i)->Accept(this , data);
}
os() << ")" ;
return nullptr;
}
void * AstNodePrinter::VisitAlternative(Alternative* that, void * data) {
RegisterNode(that);
PrintNodeLabel(that);
os() << "(:" ;
for (int i = 0 ; i < that->nodes()->length(); i++) {
os() << " " ;
that->nodes()->at(i)->Accept(this , data);
}
os() << ")" ;
return nullptr;
}
void * AstNodePrinter::VisitClassRanges(ClassRanges* that, void * data) {
RegisterNode(that);
PrintNodeLabel(that);
if (that->is_negated()) os() << "^" ;
os() << "[" ;
for (int i = 0 ; i < that->ranges(zone())->length(); i++) {
if (i > 0 ) os() << " " ;
VisitCharacterRange(that->ranges(zone())->at(i));
}
os() << "]" ;
return nullptr;
}
void * AstNodePrinter::VisitClassSetOperand(ClassSetOperand* that, void * data) {
RegisterNode(that);
PrintNodeLabel(that);
os() << "![" ;
for (int i = 0 ; i < that->ranges()->length(); i++) {
if (i > 0 ) os() << " " ;
VisitCharacterRange(that->ranges()->at(i));
}
if (that->has_strings()) {
for (auto iter : *that->strings()) {
os() << " '" ;
os() << std::string(iter.first.begin(), iter.first.end());
os() << "'" ;
}
}
os() << "]" ;
return nullptr;
}
void * AstNodePrinter::VisitClassSetExpression(ClassSetExpression* that,
void * data) {
RegisterNode(that);
PrintNodeLabel(that);
switch (that->operation()) {
case ClassSetExpression::OperationType::kUnion:
os() << "++" ;
break ;
case ClassSetExpression::OperationType::kIntersection:
os() << "&&" ;
break ;
case ClassSetExpression::OperationType::kSubtraction:
os() << "--" ;
break ;
}
if (that->is_negated()) os() << "^" ;
os() << "[" ;
for (int i = 0 ; i < that->operands()->length(); i++) {
if (i > 0 ) os() << " " ;
that->operands()->at(i)->Accept(this , data);
}
os() << "]" ;
return nullptr;
}
void * AstNodePrinter::VisitAssertion(Assertion* that, void * data) {
RegisterNode(that);
PrintNodeLabel(that);
switch (that->assertion_type()) {
case Assertion::Type::START_OF_INPUT:
os() << "@^i" ;
break ;
case Assertion::Type::END_OF_INPUT:
os() << "@$i" ;
break ;
case Assertion::Type::END_OF_BUFFER:
os() << "@$Z" ;
break ;
case Assertion::Type::START_OF_LINE:
os() << "@^l" ;
break ;
case Assertion::Type::END_OF_LINE:
os() << "@$l" ;
break ;
case Assertion::Type::BOUNDARY:
os() << "@b" ;
break ;
case Assertion::Type::NON_BOUNDARY:
os() << "@B" ;
break ;
}
return nullptr;
}
void * AstNodePrinter::VisitAtom(Atom* that, void * data) {
RegisterNode(that);
PrintNodeLabel(that);
os() << "'" ;
base::Vector<const base::uc16> chardata = that->data();
for (int i = 0 ; i < chardata.length(); i++) {
os() << AsUC16(chardata[i]);
}
os() << "'" ;
return nullptr;
}
void * AstNodePrinter::VisitText(Text* that, void * data) {
RegisterNode(that);
PrintNodeLabel(that);
if (that->elements()->length() == 1 ) {
that->elements()->at(0 ).tree()->Accept(this , data);
} else {
os() << "(!" ;
for (int i = 0 ; i < that->elements()->length(); i++) {
os() << " " ;
that->elements()->at(i).tree()->Accept(this , data);
}
os() << ")" ;
}
return nullptr;
}
void * AstNodePrinter::VisitQuantifier(Quantifier* that, void * data) {
RegisterNode(that);
PrintNodeLabel(that);
os() << "(# " << that->min() << " " ;
if (that->max() == Tree::kInfinity) {
os() << "- " ;
} else {
os() << that->max() << " " ;
}
os() << (that->is_greedy() ? "g " : that->is_possessive() ? "p " : "n " );
that->body()->Accept(this , data);
os() << ")" ;
return nullptr;
}
void * AstNodePrinter::VisitCapture(Capture* that, void * data) {
RegisterNode(that);
PrintNodeLabel(that);
os() << "(^ " ;
that->body()->Accept(this , data);
os() << ")" ;
return nullptr;
}
void * AstNodePrinter::VisitGroup(Group* that, void * data) {
RegisterNode(that);
PrintNodeLabel(that);
os() << "(?" << that->flags() << ": " ;
that->body()->Accept(this , data);
os() << ")" ;
return nullptr;
}
void * AstNodePrinter::VisitLookaround(Lookaround* that, void * data) {
RegisterNode(that);
PrintNodeLabel(that);
os() << "(" ;
os() << (that->type() == Lookaround::LOOKAHEAD ? "->" : "<-" );
os() << (that->is_positive() ? " + " : " - " );
that->body()->Accept(this , data);
os() << ")" ;
return nullptr;
}
void * AstNodePrinter::VisitBackReference(BackReference* that, void * data) {
RegisterNode(that);
PrintNodeLabel(that);
os() << "(<- " << that->captures()->first()->index();
for (int i = 1 ; i < that->captures()->length(); ++i) {
os() << "," << that->captures()->at(i)->index();
}
os() << ")" ;
return nullptr;
}
void * AstNodePrinter::VisitEmpty(Empty* that, void * data) {
RegisterNode(that);
PrintNodeLabel(that);
os() << '%' ;
return nullptr;
}
void AstNodePrinter::Print(Tree* tree) { tree->Accept(this , nullptr); }
TraceTreeScope::TraceTreeScope(Diagnostics* diagnostics)
: parent_(diagnostics ? diagnostics->trace_tree_scope() : nullptr),
depth_(parent_ != nullptr ? parent_->depth_ + 1 : -1 ),
diagnostics_(diagnostics) {
if (diagnostics_) {
diagnostics_->set_trace_tree_scope(this );
}
}
TraceTreeScope::~TraceTreeScope() {
if (diagnostics_) {
diagnostics_->set_trace_tree_scope(parent_);
}
}
void TraceTreeScope::PrintTree(Tree* tree) {
std::ostream& o = os();
AstNodePrinter* printer = diagnostics_->ast_printer();
printer->set_color(PrinterBase::Color::kRed);
o << "- " ;
printer->Print(tree);
printer->set_color(PrinterBase::Color::kDefault);
o << std::endl;
}
std::ostream& TraceTreeScope::os() {
std::ostream& os = diagnostics_->os();
for (int i = 0 ; i < depth_; i++) os << " " ;
return os;
}
} // namespace regexp
} // namespace internal
} // namespace v8
#endif // V8_ENABLE_REGEXP_DIAGNOSTICS
Messung V0.5 in Prozent C=96 H=89 G=92
¤ Dauer der Verarbeitung: 0.53 Sekunden
(vorverarbeitet am 2026-09-29)
¤
*© Formatika GbR, Deutschland