SpecialistOff.NET / Вопросы / Статьи / Фрагменты кода / Резюме / Метки / Помощь / Файлы
Назадtatsu.codegen.CodeGenerator as to allow for code generation targets different from Python. Still, the use of inline templates and rendering.Renderer hasn’t changed. See the regex example for merged modeling and code generation.竜 TatSu doesn’t impose a way to create translators with it, but it exposes the facilities it uses to generate the Python source code for parsers.
Translation in 竜 TatSu is template-based, but instead of defining or using a complex templating engine (yet another language), it relies on the simple but powerful string.Formatter of the Python standard library. The templates are simple strings that, in 竜 TatSu’s style, are inlined with the code.
To generate a parser, 竜 TatSu constructs an object model of the parsed grammar. A tatsu.codegen.CodeGenerator instance matches model objects to classes that descend from tatsu.codegen.ModelRenderer and implement the translation and rendering using string templates. Templates are left-trimmed on whitespace, like Python doc-comments are. This is an example taken from 竜 TatSu’s source code:
class Lookahead(ModelRenderer):
template = '''\
with self._if():
{exp:1::}\
'''
Every attribute of the object that doesn’t start with an underscore (_) may be used as a template field, and fields can be added or modified by overriding the render_fields(fields) method. Fields themselves are lazily rendered before being expanded by the template, so a field may be an instance of a ModelRenderer descendant.
The rendering module defines a Formatter enhanced to support the rendering of items in an iterable one by one. The syntax to achieve that is:
'''
{fieldname:ind:sep:fmt}
'''
All of ind, sep, and fmt are optional, but the three colons are not. A field specified that way will be rendered using:
indent(sep.join(fmt % render(v) for v in value), ind)
The extended format can also be used with non-iterables, in which case the rendering will be:
indent(fmt % render(value), ind)
The default multiplier for ind is 4, but that can be overridden using n*m (for example 3*1) in the format.
\n) as separator will interfere with left trimming and indentation of templates. To use a newline as separator, specify it as \\n, and the renderer will understand the intention.