# Numeric XDR widths are tracked in a dictionary that is keyed # by type_name because sometimes a caller has nothing more than # the type_name to use to figure out the numeric width.
max_widths = { "void": 0, "bool": 1, "int": 1, "unsigned_int": 1, "long": 1, "unsigned_long": 1, "hyper": 2, "unsigned_hyper": 2,
}
@dataclass class _XdrAst(ast_utils.Ast): """Base class for the XDR abstract syntax tree"""
@dataclass class _XdrIdentifier(_XdrAst): """Corresponds to 'identifier' in the XDR language grammar"""
symbol: str
@dataclass class _XdrValue(_XdrAst): """Corresponds to 'value' in the XDR language grammar"""
value: str
@dataclass class _XdrConstantValue(_XdrAst): """Corresponds to 'constant' in the XDR language grammar"""
value: int
@dataclass class _XdrTypeSpecifier(_XdrAst): """Corresponds to 'type_specifier' in the XDR language grammar"""
type_name: str
c_classifier: str = ""
@dataclass class _XdrDefinedType(_XdrTypeSpecifier): """Corresponds to a type defined by the input specification"""
def symbolic_width(self) -> List: """Return list containing XDR width of type's components""" return [get_header_name().upper() + "_" + self.type_name + "_sz"]
def __post_init__(self): if self.type_name in structs:
self.c_classifier = "struct "
symbolic_widths[self.type_name] = self.symbolic_width()
@dataclass class _XdrBuiltInType(_XdrTypeSpecifier): """Corresponds to a built-in XDR type"""
def symbolic_width(self) -> List: """Return list containing XDR width of type's components""" return symbolic_widths[self.type_name]
@dataclass class _XdrDeclaration(_XdrAst): """Base class of XDR type declarations"""
@dataclass class _XdrFixedLengthOpaque(_XdrDeclaration): """A fixed-length opaque declaration"""
@dataclass class _XdrStruct(_XdrAst): """An XDR struct definition"""
name: str
fields: List[_XdrDeclaration]
def max_width(self) -> int: """Return width of type in XDR_UNITS"""
width = 0 for field in self.fields:
width += field.max_width() return width
def symbolic_width(self) -> List: """Return list containing XDR width of type's components"""
widths = [] for field in self.fields:
widths += field.symbolic_width() return widths
def max_width(self) -> int: """Return width of type in XDR_UNITS"""
max_width = 0 for case in self.cases: if case.arm.max_width() > max_width:
max_width = case.arm.max_width() if self.default: if self.default.arm.max_width() > max_width:
max_width = self.default.arm.max_width() return 1 + max_width
def symbolic_width(self) -> List: """Return list containing XDR width of type's components"""
max_width = 0 for case in self.cases: if case.arm.max_width() > max_width:
max_width = case.arm.max_width()
width = case.arm.symbolic_width() if self.default: if self.default.arm.max_width() > max_width:
max_width = self.default.arm.max_width()
width = self.default.arm.symbolic_width() return symbolic_widths[self.discriminant.name] + width
@dataclass class _RpcProgram(_XdrAst): """RPC program definition"""
name: str
number: str
versions: List[_RpcVersion]
@dataclass class _Pragma(_XdrAst): """Empty class for pragma directives"""
@dataclass class Definition(_XdrAst, ast_utils.WithMeta): """Corresponds to 'definition' in the grammar"""
meta: Meta
value: _XdrAst
@dataclass class Specification(_XdrAst, ast_utils.AsList): """Corresponds to 'specification' in the grammar"""
definitions: List[Definition]
class ParseToAst(Transformer): """Functions that transform productions into AST nodes"""
def identifier(self, children): """Instantiate one _XdrIdentifier object""" return _XdrIdentifier(children[0].value)
def value(self, children): """Instantiate one _XdrValue object""" if isinstance(children[0], _XdrIdentifier): return _XdrValue(children[0].symbol) return _XdrValue(children[0].children[0].value)
def constant(self, children): """Instantiate one _XdrConstantValue object"""
match children[0].data:
case "decimal_constant":
value = int(children[0].children[0].value, base=10)
case "hexadecimal_constant":
value = int(children[0].children[0].value, base=16)
case "octal_constant":
value = int(children[0].children[0].value, base=8) return _XdrConstantValue(value)
def type_specifier(self, children): """Instantiate one _XdrTypeSpecifier object""" if isinstance(children[0], _XdrIdentifier):
name = children[0].symbol return _XdrDefinedType(type_name=name)
name = children[0].data.value return _XdrBuiltInType(type_name=name)
def constant_def(self, children): """Instantiate one _XdrConstant object"""
name = children[0].symbol
value = children[1].value return _XdrConstant(name, value)
# cel: Python can compute a min() and max() for the enumerator values # so that the generated code can perform proper range checking. def enum(self, children): """Instantiate one _XdrEnum object"""
enum_name = children[0].symbol
i = 0
enumerators = []
body = children[1] while i < len(body.children):
name = body.children[i].symbol
value = body.children[i + 1].value
enumerators.append(_XdrEnumerator(name, value))
i = i + 2
return _XdrEnum(enum_name, 0, 0, enumerators)
def fixed_length_opaque(self, children): """Instantiate one _XdrFixedLengthOpaque declaration object"""
name = children[0].symbol
size = children[1].value
return _XdrFixedLengthOpaque(name, size)
def variable_length_opaque(self, children): """Instantiate one _XdrVariableLengthOpaque declaration object"""
name = children[0].symbol if children[1] isnotNone:
maxsize = children[1].value else:
maxsize = "0"
return _XdrVariableLengthOpaque(name, maxsize)
def string(self, children): """Instantiate one _XdrString declaration object"""
name = children[0].symbol if children[1] isnotNone:
maxsize = children[1].value else:
maxsize = "0"
return _XdrString(name, maxsize)
def fixed_length_array(self, children): """Instantiate one _XdrFixedLengthArray declaration object"""
spec = children[0]
name = children[1].symbol
size = children[2].value
return _XdrFixedLengthArray(name, spec, size)
def variable_length_array(self, children): """Instantiate one _XdrVariableLengthArray declaration object"""
spec = children[0]
name = children[1].symbol if children[2] isnotNone:
maxsize = children[2].value else:
maxsize = "0"
def optional_data(self, children): """Instantiate one _XdrOptionalData declaration object"""
spec = children[0]
name = children[1].symbol
return _XdrOptionalData(name, spec)
def basic(self, children): """Instantiate one _XdrBasic object"""
spec = children[0]
name = children[1].symbol
return _XdrBasic(name, spec)
def void(self, children): """Instantiate one _XdrVoid declaration object"""
return _XdrVoid()
def struct(self, children): """Instantiate one _XdrStruct object"""
name = children[0].symbol
fields = children[1].children
last_field = fields[-1] if (
isinstance(last_field, _XdrOptionalData) and name == last_field.spec.type_name
): return _XdrPointer(name, fields)
return _XdrStruct(name, fields)
def typedef(self, children): """Instantiate one _XdrTypedef object"""
new_type = children[0]
return _XdrTypedef(new_type)
def case_spec(self, children): """Instantiate one _XdrCaseSpec object"""
values = [] for item in children[0:-1]:
values.append(item.value)
arm = children[-1]
return _XdrCaseSpec(values, arm)
def default_spec(self, children): """Instantiate one _XdrDefaultSpec object"""
arm = children[0]
return _XdrDefaultSpec(arm)
def union(self, children): """Instantiate one _XdrUnion object"""
name = children[0].symbol
def procedure_def(self, children): """Instantiate one _RpcProcedure object"""
result = children[0]
name = children[1].symbol
argument = children[2]
number = children[3].value
def version_def(self, children): """Instantiate one _RpcVersion object"""
name = children[0].symbol
number = children[-1].value
procedures = children[1:-1]
return _RpcVersion(name, number, procedures)
def program_def(self, children): """Instantiate one _RpcProgram object"""
name = children[0].symbol
number = children[-1].value
versions = children[1:-1]
return _RpcProgram(name, number, versions)
def pragma_def(self, children): """Instantiate one _Pragma object"""
directive = children[0].children[0].data
match directive:
case "big_endian_directive":
big_endian.append(children[1].symbol)
case "exclude_directive":
excluded_apis.append(children[1].symbol)
case "header_directive": global header_name
header_name = children[1].symbol
case "public_directive":
public_apis.append(children[1].symbol)
case _: raise NotImplementedError("Directive not supported") return _Pragma()
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.