forked from OSchip/llvm-project
86 lines
3.7 KiB
TableGen
86 lines
3.7 KiB
TableGen
//===- Syntax.td - TableGen metamodel for syntax::Node hierarchy ----------===//
|
|
//
|
|
// 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 tree representation of the is C++ syntax is quite regular.
|
|
//
|
|
// There are 4 archetypes of nodes in the syntax tree:
|
|
// - Leaves, owning exactly one token. (syntax::Leaf)
|
|
// - Sequences, with a fixed list of children that should appear in order.
|
|
// The concrete node defines a Role sequence which identifies the children.
|
|
// The type of child in each role is also constrained.
|
|
// - Lists, with children in alternating Element/Delimiter roles. (syntax::List)
|
|
// The concrete node defines the element type, delimiters are always leaves.
|
|
// - Alternatives, where several different node types are allowed.
|
|
// These are modeled as abstract types with inheritance (e.g. Declaration).
|
|
//
|
|
// This file defines TableGen classes modelling these archetypes.
|
|
// The concrete nodes are defined in terms of these classes in Nodes.td.
|
|
//
|
|
// The C++ classes for the archetypes themselves are written by hand, and the
|
|
// concrete node classes will be generated. Migration to TableGen is not
|
|
// complete, so currently there is a mix of generated and hand-authored code.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Syntax is any constraint on constructs that can appear somewhere.
|
|
class Syntax;
|
|
class Optional<Syntax inner_> : Syntax { Syntax inner = inner_; }
|
|
class AnyToken<list<string> kinds_> : Syntax { list<string> kinds = kinds_; }
|
|
class Token<string kind_> : AnyToken<[kind_]>;
|
|
class Keyword<string kw> : Token<!strconcat("kw_", kw)>;
|
|
|
|
// Defs derived from NodeType correspond to syntax tree node types.
|
|
// NodeType is also a syntax constraint: one node of this type.
|
|
class NodeType : Syntax {
|
|
// The NodeType that this node is derived from in the Node class hierarchy.
|
|
NodeType base = ?;
|
|
// Documentation for this Node subclass.
|
|
string documentation;
|
|
}
|
|
|
|
// A node type which is defined in Nodes.h rather than by generated code.
|
|
// We merely specify the inheritance hierarchy here.
|
|
class External<NodeType base_> : NodeType { let base = base_; }
|
|
|
|
// Special nodes defined here.
|
|
def Node : External<?> {}
|
|
def Leaf : External<Node> {}
|
|
def Tree : External<Node> {}
|
|
|
|
// An abstract node type which merely serves as a base for more specific types.
|
|
//
|
|
// This corresponds to an alternative rule in the grammar, such as:
|
|
// Statement = IfStatement | ForStatement | ...
|
|
// Statement is modeled using Alternatives, and IfStatement.base is Statement.
|
|
class Alternatives<NodeType base_ = Tree> : NodeType { let base = base_; }
|
|
|
|
// A node type which may contain anything and has no specific accessors.
|
|
// These are generally placeholders for a more precise implementation.
|
|
class Unconstrained<NodeType base_ = Tree> : NodeType { let base = base_; }
|
|
|
|
class Role<string role_, Syntax syntax_> {
|
|
string role = role_;
|
|
Syntax syntax = syntax_;
|
|
}
|
|
|
|
// A node which contains a fixed sequence of children in a particular order.
|
|
//
|
|
// Each child is characterized by a role (unique within the sequence), and
|
|
// has an allowed base type for the node.
|
|
// The role sequence and role/type match are enforced invariants of the class.
|
|
//
|
|
// We also record whether the child is required to be present, and which tokens
|
|
// are permitted (for Leaf nodes). These invariants are not enforced.
|
|
class Sequence<NodeType base_ = Tree> : NodeType {
|
|
let base = base_;
|
|
// Children must be Role or have a default role derived from the NodeType.
|
|
list<Role> children;
|
|
}
|
|
|
|
// FIXME: add list archetype.
|