@@ -1581,11 +1581,6 @@ class Rule:
15811581 parenthesized block (...)
15821582 - ``operands`` is empty
15831583
1584- It is intepreted as a reference rule if and only if:
1585-
1586- - the first condition above does *not* apply
1587- - the second condition above applies
1588-
15891584 operands : tuple of operands
15901585 Each operand can have one of the following types:
15911586
@@ -1596,11 +1591,10 @@ class Rule:
15961591 - ``Variable``
15971592 - ``Rule``
15981593
1599- If no operand is specified, then the rule is:
1600-
1601- - a standard rule if ``name`` is the verbatim representation of an
1602- entire rule
1603- - a reference rule if ``name`` does not satisfy the condition above
1594+ is_reference : bool, default ``False``
1595+ If set to ``True``, then the rule is serialized as a reference rule:
1596+ ``Rule(Operand1, Operand2, ...)`` is serialized as
1597+ ``[Operand1, Operand2, ...]``.
16041598
16051599 Attributes
16061600 ----------
@@ -1615,9 +1609,15 @@ class Rule:
16151609 - float
16161610 - ``Variable``
16171611 - ``Rule``
1612+
1613+ is_reference : bool
1614+ The reference status of the rule.
1615+
1616+ .. note::
1617+ This attribute cannot be changed on a `Rule` instance.
16181618 """
16191619
1620- def __init__ (self , name , * operands ):
1620+ def __init__ (self , name , * operands , is_reference = False ):
16211621 """See class docstring"""
16221622 # Check input parameters
16231623 if not is_string_like (name ):
@@ -1639,12 +1639,19 @@ def __init__(self, name, *operands):
16391639 "upper-scoped Rule" ,
16401640 )
16411641 )
1642- if not name :
1642+ if not isinstance (is_reference , bool ):
1643+ raise TypeError (type_error_message ("is_reference" , is_reference , bool ))
1644+ if not is_reference and not name :
16431645 raise ValueError ("'name' must be a non-empty string" )
16441646
16451647 # Initialize attributes
16461648 self .name = name
16471649 self .operands = operands
1650+ self ._is_reference = is_reference
1651+
1652+ @property
1653+ def is_reference (self ):
1654+ return self ._is_reference
16481655
16491656 def __repr__ (self ):
16501657 stream = io .BytesIO ()
@@ -1673,21 +1680,24 @@ def write(self, writer):
16731680 ----------
16741681 writer : `.KhiopsOutputWriter`
16751682 Output writer.
1683+
1684+ .. note::
1685+ If ``self.is_reference`` is set, then ``self.name`` is not included in the serialization.
16761686 """
16771687 # Check the type of the writer
16781688 if not isinstance (writer , KhiopsOutputWriter ):
16791689 raise TypeError (type_error_message ("writer" , writer , KhiopsOutputWriter ))
16801690
16811691 # Write standard rule
1682- rule_pattern = r"^[A-Z]([a-zA-Z]*)\(.*\)"
1692+ rule_pattern = r"^[A-Z]([a-zA-Z]*)\(? .*\)?$ "
16831693 rule_regex = re .compile (rule_pattern )
16841694 bytes_rule_regex = re .compile (bytes (rule_pattern , encoding = "ascii" ))
16851695 if self .operands :
1686- if isinstance ( self .name , str ) :
1687- writer .write (f" { _format_name ( self . name ) } ( " )
1696+ if self .is_reference :
1697+ writer .write ("[ " )
16881698 else :
1689- assert isinstance ( self .name , bytes )
1690- writer .write (f" { _format_name ( self . name ). decode ( 'ascii' ) } (" )
1699+ writer . write ( _format_name ( self .name ) )
1700+ writer .write (" (" )
16911701
16921702 # Write operand, according to its type
16931703 # Variable operands have their name written only
@@ -1705,7 +1715,10 @@ def write(self, writer):
17051715 writer .write (str (operand ))
17061716 if i < len (self .operands ) - 1 :
17071717 writer .write (", " )
1708- writer .write (")" )
1718+ if self .is_reference :
1719+ writer .write ("]" )
1720+ else :
1721+ writer .write (")" )
17091722 # Write verbatim-given rule
17101723 elif (
17111724 isinstance (self .name , str )
@@ -1714,11 +1727,6 @@ def write(self, writer):
17141727 and bytes_rule_regex .match (self .name )
17151728 ):
17161729 writer .write (self .name )
1717- # Write rule as a reference rule
1718- else :
1719- writer .write ("[" )
1720- writer .write (self .name )
1721- writer .write ("]" )
17221730
17231731
17241732class MetaData :
0 commit comments