def _typespec(rule, default_base=True):
    if not _get_node_class_name(rule):
        return TypeSpec(None, None)

    spec = rule.params[0].split(BASE_CLASS_TOKEN)
    class_name = safe_name(spec[0])
    base = None
    bases = spec[1:]
    if bases:
        base = safe_name(bases[0])
    elif default_base:
        base = 'ModelBase'
    return TypeSpec(class_name, base)
Exemplo n.º 2
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 '')
Exemplo n.º 3
0
    def make_defines_declaration(self):
        defines = compress_seq(self.defines())
        ldefs = oset(safe_name(d) for d, l in defines if l)
        sdefs = oset(
            safe_name(d) for d, l in defines if not l and d not in ldefs)

        if not (sdefs or ldefs):
            return ''
        else:
            sdefs = '[%s]' % ', '.join(sorted(repr(d) for d in sdefs))
            ldefs = '[%s]' % ', '.join(sorted(repr(d) for d in ldefs))
            if not ldefs:
                return '\n\n    self._define(%s, %s)' % (sdefs, ldefs)
            else:
                return indent('\n' + trim(self.define_template %
                                          (sdefs, ldefs)))
Exemplo n.º 4
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 = repr(whitespace)
        else:
            whitespace = 're.compile({0})'.format(repr(whitespace))

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

        comments_re = repr(self.node.directives.get('comments'))
        eol_comments_re = repr(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 = repr(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," % repr(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,
        )
Exemplo n.º 5
0
def _typespec(rule):
    if not _get_node_class_name(rule):
        return []

    spec = rule.params[0].split(BASE_CLASS_TOKEN)
    class_names = [safe_name(n) for n in spec] + ['ModelBase']

    typespec = []
    for i, class_name in enumerate(class_names[:-1]):
        base = class_names[i + 1]
        typespec.append(TypeSpec(class_name, base))

    return typespec
Exemplo n.º 6
0
    def _find_semantic_action(self, name):
        if self.semantics is None:
            return None, None

        postproc = getattr(self.semantics, '_postproc', None)

        action = getattr(self.semantics, safe_name(name), None)
        if not callable(action):
            action = getattr(self.semantics, '_default', None)

        if not callable(action):
            action = None
        if not callable(postproc):
            postproc = None

        return action, postproc
Exemplo n.º 7
0
    def render_fields(self, fields):
        defs = [safe_name(d) for d, l in compress_seq(self.defines())]
        defs = list(sorted(set(defs)))
        spec = fields["spec"]

        kwargs = '\n'.join('%s = None' % d for d in defs)
        if kwargs:
            kwargs = indent(kwargs)
        else:
            kwargs = indent('pass')

        fields.update(
            class_name=spec.class_name,
            base=spec.base,
            kwargs=kwargs,
        )
Exemplo n.º 8
0
    def _find_semantic_action(self, name):
        if self.semantics is None:
            return None, None

        postproc = getattr(self.semantics, '_postproc', None)

        action = getattr(self.semantics, safe_name(name), None)
        if not callable(action):
            action = getattr(self.semantics, '_default', None)

        if not callable(action):
            action = None
        if not callable(postproc):
            postproc = None

        return action, postproc
    def render_fields(self, fields):
        defs = [safe_name(d) for d, l in compress_seq(self.defines())]
        defs = list(sorted(set(defs)))

        kwargs = '\n'.join('%s = None' % d for d in defs)
        if kwargs:
            kwargs = indent(kwargs)
        else:
            kwargs = indent('pass')

        spec = _typespec(self.node)

        fields.update(
            class_name=spec.class_name,
            base=spec.base,
            kwargs=kwargs,
        )
Exemplo n.º 10
0
    def generate(self, grammar: grammar.Grammar) -> str:
        """entry point of this class"""
        for rule_name in grammar.rules:
            # TODO: escape keywords, special chars, etc.
            type_name = safe_name(rule_name)
            assert type_name not in self.used_global_names
            self.rule_name_to_type_name[rule_name] = type_name
            self.used_global_names.add(type_name)

        blocks = []
        for (rule_name, rule) in grammar.rules.items():
            code = self.node_to_type_code(rule_name, rule, local=False)
            self.generated_global_types.add(self.rule_name_to_type_name[rule_name])
            blocks.append(code)

        blocks.append(self.grammar_to_semantics_code(grammar))

        return "\n\n".join(blocks)
Exemplo n.º 11
0
 def render_fields(self, fields):
     fields.update(n=self.counter(), name=safe_name(self.node.name))