示例#1
0
    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
示例#2
0
 def expr(self, children):
     if len(children) == 3:
         base, mi, ma = children
         if int(mi.value) == 0:
             if int(ma.value) == 1:
                 return Optional(base)
             return ZeroOrMore(base, Comment(f'{mi.value}..{ma.value}'))
         else:
             return OneOrMore(base, Comment(f'{mi.value}..{ma.value}'))
     base, op = children
     if op.type != 'OP':
         return OneOrMore(base, Comment(f'{op.value} times'))
     if op.value == '+':
         return OneOrMore(base)
     elif op.value == '*':
         return ZeroOrMore(base)
     elif op.value == '?':
         return Optional(base)
     else:
         raise ValueError(f"Unsupported Operator {op!r}")
示例#3
0
import sys
from railroad import Diagram, Choice, OneOrMore

d = Diagram("A",
            Choice(0, "B", "C"),
            OneOrMore("D"))


with open('diagram.html', 'w') as f:
    d.writeSvg(f.write)
def token():
    return OneOrMore(Choice(0, alphanum(), tspecials()))
def isdn_subaddress():
    return Sequence(";isub=", OneOrMore(NonTerminal("uric")))
def pvalue():
    return OneOrMore(NonTerminal("paramchar"))
def pname():
    return OneOrMore(Choice(0, alphanum(), "-"))
def extension():
    return Sequence(";ext=", OneOrMore(NonTerminal("phonedigit")))
示例#9
0
def segment_nz():
    return OneOrMore(Choice(0, *pchar()))
示例#10
0
def ipvfuture():
    return [
        "v",
        OneOrMore(NonTerminal("HEXDIG")), ".",
        OneOrMore(Choice(0, unreserved(), sub_delims(), ":"))
    ]