AST Class Hierarchy¶
This document explains the class hierarchy and inheritance relationships in the PSS AST.
Inheritance Overview¶
The PSS AST follows a clear inheritance hierarchy with ScopeChild as the root base class for most nodes.
Key Base Classes¶
- ScopeChild
Base class for most AST nodes. Provides:
parentpointer to containing scopelocationinformation for error reportingindexwithin parent’s children listassocDatafor user-defined metadata
- Scope (extends ScopeChild)
Container for child nodes. Provides:
childrenlist of contained ScopeChild nodesendLocationfor closing brace position
- NamedScope (extends Scope)
Scope with an identifier name:
name(ExprId) for the scope identifierUsed for packages, types, etc.
- NamedScopeChild (extends ScopeChild)
Child node with a name but not a scope:
name(ExprId) for the identifierUsed for fields, parameters, enum items, etc.
Complete Class Hierarchy¶
Core Structure¶
ScopeChild (base for all AST nodes)
├── Scope (container for children)
│ ├── GlobalScope (file root)
│ ├── NamedScope (named container)
│ │ ├── PackageScope (package)
│ │ └── TypeScope (named type)
│ │ ├── Action (action declaration)
│ │ ├── Component (component declaration)
│ │ └── Struct (struct/buffer/resource/stream/state)
│ ├── ConstraintScope (constraint container)
│ │ └── ConstraintBlock (named constraint)
│ ├── ExecScope (exec block scope)
│ └── ExtendType (type extension)
├── NamedScopeChild (named node, not a scope)
│ ├── Field (data field)
│ ├── FieldRef (reference field)
│ ├── FieldClaim (resource claim)
│ ├── FieldCompRef (component reference)
│ ├── EnumDecl (enum declaration)
│ ├── EnumItem (enum value)
│ ├── FunctionParamDecl (function parameter)
│ └── ExtendEnum (enum extension)
├── ScopeChildRef (reference to another node)
├── PackageImportStmt (import statement)
├── PyImportStmt (Python import)
└── PyImportFromStmt (Python from..import)
Type System Hierarchy¶
ScopeChild
└── DataType (base type)
├── DataTypeBool (boolean)
├── DataTypeInt (integer/bit)
├── DataTypeString (string)
├── DataTypeEnum (enum reference)
├── DataTypeUserDefined (user type reference)
├── DataTypeRef (reference type)
├── DataTypeChandle (C handle)
└── DataTypePyObj (Python object)
Expression Hierarchy¶
Expr (base expression)
├── ExprBool (boolean literal)
├── ExprNumber (numeric literal)
│ ├── ExprSignedNumber
│ └── ExprUnsignedNumber
├── ExprString (string literal)
├── ExprNull (null literal)
├── ExprId (identifier)
├── ExprHierarchicalId (qualified identifier)
├── ExprBin (binary operation)
├── ExprUnary (unary operation)
├── ExprCond (ternary ? :)
├── ExprCast (type cast)
├── ExprIn (in operator)
├── ExprCompileHas (compile-time has)
├── ExprSubscript (array subscript)
├── ExprBitSlice (bit slice)
├── ExprSubstring (substring)
├── ExprRefPath (reference path)
│ ├── ExprRefPathContext
│ ├── ExprRefPathStatic
│ │ ├── ExprRefPathStaticFunc
│ │ └── ExprRefPathStaticRooted
│ └── ExprRefPathSuper
├── ExprStaticRefPath (static reference)
├── ExprAggrLiteral (aggregate literal)
│ ├── ExprAggrEmpty ({ })
│ ├── ExprAggrList ({ a, b, c })
│ ├── ExprAggrMap ({ key: val })
│ └── ExprAggrStruct ({ .field = val })
├── ExprListLiteral (list literal)
├── ExprStructLiteral (struct literal)
├── ExprDomainOpenRangeList (domain range)
├── ExprDomainOpenRangeValue
├── ExprOpenRangeList (open range)
└── ExprOpenRangeValue
Activity Hierarchy¶
ScopeChild
├── ActivityStmt (base activity)
│ ├── ActivityDecl (activity declaration)
│ ├── ActivityLabeledStmt (labeled statement)
│ │ ├── ActivityActionHandleTraversal (action invoke)
│ │ ├── ActivityActionTypeTraversal (type traverse)
│ │ ├── ActivityAtomicBlock (atomic)
│ │ └── ActivitySuper (super call)
│ └── ActivityLabeledScope (labeled scope)
│ ├── ActivitySequence (sequential)
│ ├── ActivityParallel (parallel)
│ ├── ActivitySchedule (scheduled)
│ ├── ActivitySelect (select)
│ ├── ActivityRepeatCount (repeat N)
│ ├── ActivityRepeatWhile (repeat while)
│ ├── ActivityForeach (foreach)
│ ├── ActivityReplicate (replicate)
│ ├── ActivityIfElse (if-else)
│ └── ActivityMatch (match)
├── ActivitySelectBranch (select branch)
├── ActivityMatchChoice (match case)
├── ActivityBindStmt (bind)
├── ActivityConstraint (constraint)
├── ActivitySchedulingConstraint (scheduling constraint)
└── ActivityJoinSpec (join specification)
├── ActivityJoinSpecNone
├── ActivityJoinSpecFirst
├── ActivityJoinSpecBranch
└── ActivityJoinSpecSelect
Constraint Hierarchy¶
ScopeChild
├── ConstraintScope (constraint container)
│ └── ConstraintBlock (named constraint block)
├── ConstraintStmt (base constraint)
│ ├── ConstraintScope (also extends here)
│ ├── ConstraintStmtExpr (expression constraint)
│ ├── ConstraintStmtField (field in loop)
│ ├── ConstraintStmtForeach (foreach loop)
│ ├── ConstraintStmtForall (forall quantifier)
│ ├── ConstraintStmtIf (conditional)
│ ├── ConstraintStmtImplication (implication)
│ ├── ConstraintStmtUnique (uniqueness)
│ ├── ConstraintStmtDefault (default value)
│ └── ConstraintStmtDefaultDisable (disable default)
└── ConstraintSymbolScope (symbol scope)
Procedural Code Hierarchy¶
ScopeChild
├── ExecBlock (exec block)
├── ExecScope (exec scope)
├── ExecStmt (base exec statement)
│ ├── ProceduralStmtAssignment
│ ├── ProceduralStmtExpr
│ ├── ProceduralStmtFunctionCall
│ ├── ProceduralStmtReturn
│ ├── ProceduralStmtDataDeclaration
│ ├── ProceduralStmtBody
│ ├── ProceduralStmtSymbolBodyScope
│ ├── ProceduralStmtIfElse
│ ├── ProceduralStmtIfClause
│ ├── ProceduralStmtWhile
│ ├── ProceduralStmtRepeat
│ ├── ProceduralStmtRepeatWhile
│ ├── ProceduralStmtForeach
│ ├── ProceduralStmtMatch
│ ├── ProceduralStmtMatchChoice
│ ├── ProceduralStmtBreak
│ ├── ProceduralStmtContinue
│ ├── ProceduralStmtYield
│ └── ProceduralStmtRandomize
├── ExecTargetTemplateBlock
└── ExecTargetTemplateParam
Function Hierarchy¶
ScopeChild
├── FunctionDefinition (function with body)
├── FunctionPrototype (function signature)
├── FunctionImport (base import)
│ ├── FunctionImportType
│ └── FunctionImportProto
├── NamedScopeChild
│ └── FunctionParamDecl (parameter)
└── MethodParameterList (parameter list)
Monitor Hierarchy (PSS 3.0)¶
TypeScope
└── Monitor (monitor declaration)
ScopeChild
├── MonitorActivityDecl (activity declaration)
├── MonitorActivityStmt (base monitor activity)
│ ├── MonitorActivitySequence
│ ├── MonitorActivityConcat (##)
│ ├── MonitorActivityEventually
│ ├── MonitorActivityOverlap
│ ├── MonitorActivitySchedule
│ ├── MonitorActivitySelect
│ ├── MonitorActivityRepeatCount
│ ├── MonitorActivityRepeatWhile
│ ├── MonitorActivityIfElse
│ ├── MonitorActivityMatch
│ ├── MonitorActivityActionTraversal
│ └── MonitorActivityMonitorTraversal
├── MonitorActivitySelectBranch
├── MonitorActivityMatchChoice
├── MonitorConstraint
├── CoverStmtInline
└── CoverStmtReference
Template Hierarchy¶
ScopeChild
├── TemplateParamDeclList
├── TemplateParamDecl (base parameter)
│ ├── TemplateValueParamDecl (value param)
│ ├── TemplateGenericTypeParamDecl (type param)
│ └── TemplateCategoryTypeParamDecl (constrained type)
├── TemplateParamValueList
└── TemplateParamValue (base value)
├── TemplateParamExprValue (expression value)
└── TemplateParamTypeValue (type value)
Symbol Resolution Hierarchy¶
ScopeChild
├── SymbolChild (symbol tree base)
│ └── SymbolChildrenScope (with children)
│ └── SymbolScope (symbol scope)
│ ├── RootSymbolScope (root)
│ ├── SymbolTypeScope (type scope)
│ ├── SymbolEnumScope (enum scope)
│ ├── SymbolFunctionScope (function scope)
│ └── SymbolExtendScope (extension scope)
├── SymbolScopeRef (scope reference)
└── SymbolImportSpec (import specification)
(Internal classes)
SymbolRefPath (reference path)
RefExpr (reference expression)
├── RefExprScopeIndex
├── RefExprTypeScopeContext
└── RefExprTypeScopeGlobal
When to Use Which Class¶
Traversing the Tree¶
Use Scope classes when:
You need to iterate over children
You’re building the physical AST structure
You’re walking the parse tree
Use SymbolScope classes when:
You need name resolution
You’re doing semantic analysis
You need cross-reference information
Creating New Nodes¶
For declarations, use:
Actionfor action declarationsComponentfor componentsStructfor structs/buffers/resources/streams/statesFieldfor data membersEnumDeclfor enumerations
For executable code, use:
ActivitySequence/ActivityParallelfor control flowExecBlockwithProceduralStmt*for procedural codeConstraintBlockwithConstraintStmt*for constraints
For expressions, use:
ExprBinfor binary operationsExprIdfor identifiersExprNumber/ExprBool/ExprStringfor literalsExprRefPathfor member access
Type Annotations¶
For field types, use:
DataTypeIntfor integers/bitsDataTypeBoolfor booleansDataTypeStringfor stringsDataTypeUserDefinedfor user-defined typesDataTypeReffor reference types
Common Design Patterns¶
Visitor Pattern¶
Implement visit() methods for each node type:
class MyVisitor:
def visit(self, node):
# Dispatch to specific visitor method
method_name = f'visit_{type(node).__name__}'
method = getattr(self, method_name, self.generic_visit)
return method(node)
def generic_visit(self, node):
# Default: visit children
if hasattr(node, 'children'):
for child in node.children:
self.visit(child)
def visit_Action(self, node):
print(f"Visiting action: {node.name.id}")
self.generic_visit(node)
def visit_Field(self, node):
print(f" Field: {node.name.id}")
Accumulator Pattern¶
Collect information while traversing:
class StatisticsCollector:
def __init__(self):
self.action_count = 0
self.constraint_count = 0
self.field_count = 0
def collect(self, node):
if isinstance(node, ast.Action):
self.action_count += 1
elif isinstance(node, ast.ConstraintBlock):
self.constraint_count += 1
elif isinstance(node, ast.Field):
self.field_count += 1
if hasattr(node, 'children'):
for child in node.children:
self.collect(child)
def report(self):
return {
'actions': self.action_count,
'constraints': self.constraint_count,
'fields': self.field_count
}
Transformer Pattern¶
Modify the AST while traversing:
class ExpressionSimplifier:
def transform(self, expr):
if isinstance(expr, ast.ExprBin):
# Simplify: x + 0 => x
if (expr.op == ast.ExprBinOp.BinOp_Add and
isinstance(expr.rhs, ast.ExprNumber) and
expr.rhs.val == 0):
return expr.lhs
# Recursively simplify operands
expr.lhs = self.transform(expr.lhs)
expr.rhs = self.transform(expr.rhs)
return expr
Next Steps¶
See AST Usage Guide for practical examples
Read API Reference for detailed class documentation
Explore AST Structure for AST organization details