//===-- HTMLForest.cpp - browser-based parse forest explorer //---------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // The plain text forest node dump (clang-pseudo -print-forest) is useful but // hard to reconcile with the code being examined, especially when it is large. // // HTMLForest produces a self-contained HTML file containing both the code and // the forest representation, linking them interactively with javascript. // At any given time, a single parse tree is shown (ambiguities resolved). // The user can switch between ambiguous alternatives. // // +-------+---------------+ // | | +-----+| // | #tree | #code |#info|| // | | +-----+| // | | | // +-------+---------------+ // // #tree is a hierarchical view of the nodes (nested <ul>s), like -print-forest. // (It is a simple tree, not a DAG, because ambiguities have been resolved). // Like -print-forest, trivial sequences are collapsed (expression~IDENTIFIER). // // #code is the source code, annotated with <span>s marking the node ranges. // These spans are usually invisible (exception: ambiguities are marked), but // they are used to show and change the selection. // // #info is a floating box that shows details of the currently selected node: // - rule (for sequence nodes). Abbreviated rules are also shown. // - alternatives (for ambiguous nodes). The user can choose an alternative. // - ancestors. The parent nodes show how this node fits in translation-unit. // // There are two types of 'active' node: // - *highlight* is what the cursor is over, and is colored blue. // Near ancestors are shaded faintly (onion-skin) to show local structure. // - *selection* is set by clicking. // The #info box shows the selection, and selected nodes have a dashed ring. // //===----------------------------------------------------------------------===// #include "clang-pseudo/Disambiguate.h" #include "clang-pseudo/Forest.h" #include "clang-pseudo/grammar/Grammar.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/JSON.h" #include "llvm/Support/raw_ostream.h" namespace clang { namespace pseudo { namespace { // Defines const char HTMLForest_css[] = "...contents of HTMLForest.css..."; etc #include "HTMLForestResources.inc" struct Writer { … }; void Writer::writeCode() { … } // Writes a JSON array of forest nodes. Items are e.g.: // {kind:'sequence', symbol:'compound-stmt', children:[5,8,33], // rule:'compound-stmt := ...'} {kind:'terminal', symbol:'VOID', token:'t52'} // {kind:'ambiguous', symbol:'type-specifier', children:[3,100] selected:3} // {kind:'opaque', symbol:'statement-seq', firstToken:'t5', lastToken:'t6'} void Writer::writeForestJSON() { … } } // namespace // We only accept the derived stream here. // FIXME: allow the original stream instead? void writeHTMLForest(llvm::raw_ostream &OS, const Grammar &G, const ForestNode &Root, const Disambiguation &Disambig, const TokenStream &Stream) { … } } // namespace pseudo } // namespace clang