예제 #1
0
    def _to_str(self, lean=False):
        regex_directives = {'comments', 'eol_comments', 'whitespace'}
        ustr_directives = {'comments', 'grammar'}
        string_directives = {'namechars'}

        directives = ''
        for directive, value in self.directives.items():
            fmt = dict(
                name=directive,
                frame='/' if directive in regex_directives else '',
                value=(
                    urepr(value) if directive in string_directives
                    else ustr(value) if directive in ustr_directives
                    else value
                ),
            )
            directives += '@@{name} :: {frame}{value}{frame}\n'.format(**fmt)
        if directives:
            directives += '\n'

        keywords = '\n'.join(
            '@@keyword :: ' + ' '.join(urepr(k) for k in c if k is not None)
            for c in chunks(sorted(self.keywords), 8)
        ).strip()
        keywords = '\n\n' + keywords + '\n' if keywords else ''

        rules = (
            '\n\n'.join(ustr(rule._to_str(lean=lean))
                        for rule in self.rules)
        ).rstrip() + '\n'
        return directives + keywords + rules
예제 #2
0
    def test_multiline_pattern(self):
        grammar = r'''
            start =
            /(?x)
            foo
            bar
            / $ ;
        '''
        model = compile(grammar=trim(grammar))
        print(codegen(model.rules[0].exp.sequence[0]))
        self.assertEqual(
            codegen(model.rules[0].exp.sequence[0]),
            urepr("self._pattern('(?x)\nfoo\nbar\n')").strip('"\'')
        )

        grammar = r'''
            start =
            /(?x)foo\nbar
            blort/ $ ;
        '''
        model = compile(grammar=trim(grammar))
        print(codegen(model.rules[0].exp.sequence[0]))
        self.assertEqual(
            trim(codegen(model.rules[0].exp.sequence[0])),
            urepr("self._pattern('(?x)foo\\nbar\nblort')").strip(r'"\.')
        )
예제 #3
0
    def _to_str(self, lean=False):
        regex_directives = {'comments', 'eol_comments', 'whitespace'}
        ustr_directives = {'comments', 'grammar'}
        string_directives = {'namechars'}

        directives = ''
        for directive, value in self.directives.items():
            fmt = dict(
                name=directive,
                frame='/' if directive in regex_directives else '',
                value=(urepr(value) if directive in string_directives else
                       ustr(value) if directive in ustr_directives else value),
            )
            directives += '@@{name} :: {frame}{value}{frame}\n'.format(**fmt)
        if directives:
            directives += '\n'

        keywords = '\n'.join(
            '@@keyword :: ' + ' '.join(urepr(k) for k in c if k is not None)
            for c in chunks(sorted(self.keywords), 8)).strip()
        keywords = '\n\n' + keywords + '\n' if keywords else ''

        rules = ('\n\n'.join(
            ustr(rule._to_str(lean=lean))
            for rule in self.rules)).rstrip() + '\n'
        return directives + keywords + rules
예제 #4
0
    def render_fields(self, fields):
        self.reset_counter()

        params = kwparams = ''
        if self.node.params:
            params = ', '.join(
                self.param_repr(self.rend(p))
                for p in self.node.params
            )
        if self.node.kwparams:
            kwparams = ', '.join(
                '%s=%s'
                %
                (k, self.param_repr(self.rend(v)))
                for k, v in self.kwparams.items()
            )

        if params and kwparams:
            params = params + ', ' + kwparams
        elif kwparams:
            params = kwparams

        fields.update(params=params)

        defines = compress_seq(self.defines())
        ldefs = set(safe_name(d) for d, l in defines if l)
        sdefs = set(safe_name(d) for d, l in defines if not l and d not in ldefs)

        if not (sdefs or ldefs):
            sdefines = ''
        else:
            sdefs = '[%s]' % ', '.join(urepr(d) for d in sorted(sdefs))
            ldefs = '[%s]' % ', '.join(urepr(d) for d in sorted(ldefs))
            if not ldefs:
                sdefines = '\n\n    self.ast._define(%s, %s)' % (sdefs, ldefs)
            else:
                sdefines = indent(
                    '\n' +
                    trim(self.define_template % (sdefs, ldefs))
                )

        fields.update(defines=sdefines)
        fields.update(
            check_name='\n    self._check_name()' if self.is_name else '',
        )
        leftrec = self.node.is_leftrec
        fields.update(leftrec='\n@leftrec' if leftrec else '')
        fields.update(nomemo='\n@nomemo' if not self.node.is_memoizable and not leftrec else '')
예제 #5
0
 def param_repr(p):
     if isinstance(p, (int, float)):
         return ustr(p)
     elif isinstance(p, strtype) and p.isalnum():
         return ustr(p)
     else:
         return urepr(p)
예제 #6
0
 def param_repr(p):
     if isinstance(p, (int, float)):
         return ustr(p)
     elif isinstance(p, strtype) and p.isalnum():
         return ustr(p)
     else:
         return urepr(p)
예제 #7
0
    def render_fields(self, fields):
        abstract_template = trim(self.abstract_rule_template)
        abstract_rules = [
            abstract_template.format(name=safe_name(rule.name))
            for rule in self.node.rules
        ]
        abstract_rules = indent('\n'.join(abstract_rules))

        whitespace = self.node.whitespace or self.node.directives.get(
            'whitespace')
        if not whitespace:
            whitespace = 'None'
        elif isinstance(whitespace, RETYPE):
            whitespace = urepr(whitespace)
        else:
            whitespace = 're.compile({0})'.format(urepr(whitespace))

        if self.node.nameguard is not None:
            nameguard = urepr(self.node.nameguard)
        elif self.node.directives.get('nameguard') is not None:
            nameguard = self.node.directives.get('nameguard')
        else:
            nameguard = 'None'

        comments_re = urepr(self.node.directives.get('comments'))
        eol_comments_re = urepr(self.node.directives.get('eol_comments'))
        ignorecase = self.node.directives.get('ignorecase', 'None')
        left_recursion = self.node.directives.get('left_recursion', True)
        parseinfo = self.node.directives.get('parseinfo', True)

        namechars = urepr(self.node.directives.get('namechars') or '')

        rules = '\n'.join(
            [self.get_renderer(rule).render() for rule in self.node.rules])

        version = str(tuple(int(n) for n in str(timestamp()).split('.')))

        keywords = '\n'.join("    %s," % urepr(k)
                             for k in sorted(self.keywords))
        if keywords:
            keywords = '\n%s\n' % keywords

        fields.update(
            rules=indent(rules),
            start=self.node.rules[0].name,
            abstract_rules=abstract_rules,
            version=version,
            whitespace=whitespace,
            nameguard=nameguard,
            ignorecase=ignorecase,
            comments_re=comments_re,
            eol_comments_re=eol_comments_re,
            left_recursion=left_recursion,
            parseinfo=parseinfo,
            keywords=keywords,
            namechars=namechars,
        )
예제 #8
0
    def parse(self, ctx):
        with ctx._choice():
            for o in self.options:
                with ctx._option():
                    ctx.last_node = o.parse(ctx)
                    return ctx.last_node

            lookahead = ' '.join(ustr(urepr(f[0])) for f in self.lookahead() if str(f))
            if lookahead:
                ctx._error('expecting one of {%s}' % lookahead)
            ctx._error('no available options')
예제 #9
0
    def parse(self, ctx):
        with ctx._choice():
            for o in self.options:
                with ctx._option():
                    ctx.last_node = o.parse(ctx)
                    return ctx.last_node

            lookahead = ' '.join(ustr(urepr(f[0])) for f in self.lookahead() if str(f))
            if lookahead:
                ctx._error('expecting one of {%s}' % lookahead)
            ctx._error('no available options')
예제 #10
0
 def render_fields(self, fields):
     template = trim(self.option_template)
     options = [
         template.format(option=indent(self.rend(o)))
         for o in self.node.options
     ]
     options = '\n'.join(o for o in options)
     firstset = ' '.join(f[0] for f in sorted(self.node.lookahead()) if f)
     if firstset:
         error = 'expecting one of: ' + firstset
     else:
         error = 'no available options'
     fields.update(n=self.counter(),
                   options=indent(options),
                   error=urepr(error))
예제 #11
0
 def _to_str(self, lean=False):
     return urepr(self.token)
예제 #12
0
 def __init__(self, ast=None, **kwargs):
     super(Choice, self).__init__(ast=AST(options=ast))
     assert isinstance(self.options, list), urepr(self.options)
예제 #13
0
 def render_fields(self, fields):
     raw_repr = urepr(self.node.pattern)
     fields.update(pattern=raw_repr)
예제 #14
0
 def render_fields(self, fields):
     fields.update(literal=urepr(self.node.literal))
예제 #15
0
 def render_fields(self, fields):
     fields.update(token=urepr(self.node.token))
예제 #16
0
 def _to_str(self, lean=False):
     return '`%s`' % urepr(self.literal)
예제 #17
0
 def _to_str(self, lean=False):
     return '`%s`' % urepr(self.literal)
예제 #18
0
 def __init__(self, ast=None, **kwargs):
     super(Choice, self).__init__(ast=AST(options=ast))
     assert isinstance(self.options, list), urepr(self.options)
예제 #19
0
 def render_fields(self, fields):
     raw_repr = 'r' + urepr(self.node.pattern).replace("\\\\", '\\')
     fields.update(pattern=raw_repr)
예제 #20
0
 def param_repr(p):
     if isinstance(p, (int, float)):
         return ustr(p)
     else:
         return urepr(p.split(BASE_CLASS_TOKEN)[0])
예제 #21
0
 def _to_str(self, lean=False):
     return urepr(self.token)