def dec_octet(): return Choice( 0, DIGIT(), Sequence(HorizontalChoice("1", "2", "3", "4", "5", "6", "7", "8", "9"), DIGIT()), Sequence("1", DIGIT(), DIGIT()), Sequence("2", HorizontalChoice("0", "1", "2", "3", "4"), DIGIT()), Sequence("25", HorizontalChoice("0", "1", "2", "3", "4", "5")))
def parameter(): return Sequence( ";", pname(), Optional( Sequence("=", pvalue()) ) )
def hier_part(): return Optional( Choice( 0, Sequence("//", Group(Sequence(*authority()), "authority"), Group(path_abempty(), "path-abempty")), Group(path_absolute(), "path-absolute"), Group(path_rootless(), "path-rootless")))
def domainlabel(): return Choice(0, alphanum(), Sequence( alphanum(), ZeroOrMore(Sequence(alphanum(), "-")), alphanum() ) )
def generate_diagram(name, *modifiers): return NamedDiagram( name, Diagram( Sequence( name, ZeroOrMore( Sequence( copy(whitespace), Choice(0, *modifiers), ), skip=SKIP, ))))
def generate_sequence(name, *modifiers): if len(modifiers) == 1: return Sequence( name, Optional(Sequence(copy(whitespace), Choice(0, *modifiers)), skip=SKIP)) return Sequence( name, ZeroOrMore(Sequence( copy(whitespace), Choice(0, *modifiers), ), skip=SKIP), )
def local_number(): return Sequence( local_number_digits(), ZeroOrMore(NonTerminal("par")), context(), ZeroOrMore(NonTerminal("par")) )
def global_number_digits(): return Sequence( "+", ZeroOrMore(NonTerminal("phonedigit")), DIGIT(), ZeroOrMore(NonTerminal("phonedigit")) )
def recurse(p: Parser) -> Union[DiagramItem, str, None]: # Transform parsers are just ignored if isinstance(p, _Transform): return recurse(p.children[0]) elif isinstance(p, Opt): # Opt parsers are straightforwardly wrapped into an Optional return Optional(recurse(p.parser)) elif isinstance(p, _Extract): # Extract is ignored return recurse(p.parser) # For list parsers, we create a sequence with the right separator # and sub-parser. elif isinstance(p, List): sep = recurse(p.sep) if p.sep else None child = recurse(p.parser) if p.empty_valid: return ZeroOrMore(child, repeat=sep) else: return OneOrMore(child, repeat=sep) # For defers, we just return the rule name elif isinstance(p, Defer): return p.rule_name # For tokens, we return either the quoted original string, or the DSL # name. elif isinstance(p, _Token): if p._original_string: return repr(p._original_string) else: return p.val.dsl_name children = [] for c in p.children: res = recurse(c) if res is not None: children.append(res) if isinstance(p, Or): if len(children) == 0: return None children = sorted(children, key=lambda c: isinstance(c, Skip)) return Choice(0, *children) elif isinstance(p, _Row): if len(children) == 0: return Skip() return Sequence(*children) else: return None
def toplabel(): return Choice( 0, ALPHA(), Sequence( ALPHA(), ZeroOrMore(Choice(0, alphanum(), "-")), alphanum() ) )
def parameter(): return Sequence(attribute(), "=", value())
def reg_name(): return ZeroOrMore( Choice(0, unreserved(), Sequence(*pct_encoded()), sub_delims()))
def userinfo(): return ZeroOrMore( Choice(0, Group(unreserved(), "unreserved"), Group(Sequence(*pct_encoded()), "pct-encoded"), Group(sub_delims(), "sub-delims"), ":"))
def scheme(): return Sequence( ALPHA(), ZeroOrMore(HorizontalChoice(ALPHA(), DIGIT()), HorizontalChoice("+", "-", ".")))
def x_token(): return Sequence(Choice(0, "X-", "x-"), NonTerminal("token"))
def pct_encoded(): return Sequence("%", HEXDIG(), HEXDIG())
def extension(): return Sequence(";ext=", OneOrMore(NonTerminal("phonedigit")))
def context(): return Sequence(";phone-context=", NonTerminal("descriptor"))
def local_number_digits(): return Sequence( ZeroOrMore(NonTerminal("phonedigit_hex")), Choice(0, HEXDIG(), "*", "#"), ZeroOrMore(NonTerminal("phonedigit_hex")) )
def domainname(): return Sequence( ZeroOrMore(Sequence(Group(domainlabel(), "domainlabel"), ".")), Group(toplabel(), "toplabel"), Optional(".") )
def host(): return Choice(1, Sequence(*ip_literal()), Sequence(*ipv4address()), NonTerminal("reg-name"))
def mediatype(): return Sequence(Optional(Sequence(type_(), "/", subtype())), ZeroOrMore(Sequence(";", parameter())))
def dataurl(): return Sequence("data:", Optional(mediatype()), Optional(";base64"), ",", data())
def pchar(): return [ Group(unreserved(), "unreserved"), Group(Sequence(*pct_encoded()), "pct-encoded"), Group(sub_delims(), "sub-delims"), ":", "@" ]
def quoted_string(): return Sequence('"', NonTerminal("ASCII"), '"')
def global_number(): return Sequence(global_number_digits(), ZeroOrMore(NonTerminal("par")))
stroke:#000; fill:transparent; }} rect.group-box {{ stroke:gray; stroke-dasharray:10 5; fill:none; }} """ railroad.DIAGRAM_CLASS = '' railroad.DEFAULT_STYLE = css railroad.STROKE_ODD_PIXEL_LENGTH = STROKE_WIDTH % 2 == 1 railroad.CHAR_WIDTH = 7.5 padding = Sequence('padding:', Choice(0, 'zero', 'space', 'none')) case_sensitive = Sequence('case_sensitive:', Choice(0, 'true', 'false')) hour_repr = Sequence('repr:', Choice(0, '24', '12')) month_repr = Sequence('repr:', Choice(0, 'numerical', 'long', 'short')) period_case = Sequence('case:', Choice(0, 'lower', 'upper')) sign = Sequence('sign:', Choice(0, 'automatic', 'mandatory')) subsecond_digits = Sequence( 'digits:', Choice(0, '1+', '1', '2', '3', '4', '5', '6', '7', '8', '9')) weekday_repr = Sequence('repr:', Choice(0, 'long', 'short', 'sunday', 'monday')) weekday_one_indexed = Sequence('one_indexed:', Choice(0, 'false', 'true')) week_number_repr = Sequence('repr:', Choice(0, 'iso', 'sunday', 'monday')) year_repr = Sequence('repr:', Choice(0, 'full', 'last_two')) year_base = Sequence('base:', Choice(0, 'calendar', 'iso_week')) whitespace = Comment('whitespace')
def telephone_uri(): return Sequence("tel:", telephone_subscriber())
def isdn_subaddress(): return Sequence(";isub=", OneOrMore(NonTerminal("uric")))
def h16(): return Sequence( HEXDIG(), Optional( Sequence(HEXDIG(), Optional(Sequence(HEXDIG(), Optional(HEXDIG()))))))