Building a front-end DSL

Source: Internet
Author: User
Tags abstract add end expression final regular expression return domain

Currently in the traditional software development domain DSL has been more common, especially Martin Fowler's outstanding contributions. But in the front-end area is still less involved, and if the use of DSL in front-end development can also effectively reduce the number of code, improve readability . A common scenario is the building of a front-end template, which is essentially a micro-language, so you can start with a DSL perspective and use tools to quickly build a template engine for a particular front-end framework. This article will take Kissy Xtemplate as an example of how to build a front-end DSL.

Note:
This article continues to update the address:
Xtemplate at GitHub.
Xtemplate at docs.kissyui.com.
DSL is also a beginner, please errata.

First NPM installs Kissy

 npm install -g kissy

Xtemplate Sample Code

this is kissy xtemplate: {{date}}
{{#if n > n*2}}
    {{{no escape}}}
    {{each array}}
        index: {{xindex}}
        count: {{xcount}}
        value: {{value}}
        {{set t = value*2}}
        subValue:
        {{#with this.subValue}}
            {{subSubValue + ../t}}
        {{/with}}
    {{/each}}
{{else}}
    {{#custom_block param}}
        {{custom_tpl param2}}
    {{/custom_block}}
{{/if}}

Template morphology/syntax

This step is primarily to prepare for the next step in building a custom language syntax tree, which is done in the direction of using tools to automatically generate a parser (parser), and you can skip this step if you intend to write a parser (in fact you can skip this article).

Because this article pays attention to the front-end technology, so the lexical and the grammar all uses the JSON format to describe, the lexical directly uses the regular expression, the grammar uses the distortion BNF form, for example Xtemplate's lexical grammar file

The tool uses the Kissy developed LALR Parser Builder Kison.

Lexical concerns how to parse out the most basic unit of code (keywords, strings, numbers ...) from the input code. ), such as Xtemplate's partial lexical

{
    state: "t",
    regexp: /^{{/,
    token: "OPEN"
},
{
    state: "t",
    regexp: /^}}/,
    token: "CLOSE"
},
{
    state: "t",
    regexp: /^<=/,
    token: "LE"
},
{
    state: "t",
    regexp: /^\+/,
    token: "PLUS"
},
{
    state: "t",
    regexp: /^[a-zA-Z0-9_$-]+/,
    token: "ID"
},

Where state represents a single status, the lexical parsing process is also a state machine transformation state process.

Grammar parsing concerns and recognizes an effective program structure from the lexical unit, that is, a syntax-resolution tree, such as a partial syntax description of xtemplate:

{
    symbol: "Expression",
    rhs: ["ConditionalOrExpression"]
},

{
    symbol: "ConditionalOrExpression",
    rhs: ["ConditionalAndExpression"]
},
{
    symbol: "program",
    rhs: ["statements", "inverse", "statements"]
},
{
    symbol: "statement",
    rhs: ["openBlock", "program", "closeBlock"]
}

Which corresponds to the BNF form: symbol:: = RHS

Building Templates Abstract Syntax tree

The syntax lexical only describes how to recognize the template language. While the process of constructing the syntax tree needs to be built by the caller in the process of syntactic recognition, Kison supports the addition of action functions in each grammar rule item, and selectively constructs the special-shaped abstract syntax tree by means of the tool in the process of language recognition (traversal parsing tree).
For example, the Xtemplate tree node build process:

{
    symbol: "program",
    rhs: ["statements", "inverse", "statements"],
    action: function () {
        return new this.yy.ProgramNode(this.lexer.lineNumber, this.$1, this.$3);
    }
},
{
    symbol: "PrimaryExpression",
    rhs: ["path"]
},
{
    symbol: "RelationalExpression",
    rhs: ["RelationalExpression", "LE", "AdditiveExpression"],
    action: function () {
        return new this.yy.RelationalExpression(this.$1, "<=", this.$3);
    }
}

The most basic expression (primaryexpression) can be directly the value of the variable lexical unit, while the complex comparison expression and the entire program are built from the bottom up subtree.

Last use Kissy-kison command

kissy-kison -g parser.kison -m xtemplate/parser

You can generate a template parsing function module, roughly:

KISSY.add("xtemplate/parser", function(){
    function parse(code){
        // ...
    }
    return parse;
});

Template compilation

The final step is the template compilation process, the template code compiled into JavaScript code, fill in the data after the execution of the real rendering of HTML.

Call Parse

After you have parsed the function in the previous step, call the

parse(tempalteCode)

To get an abstract syntax tree, such as a piece of code for Xtemplate:

{{#each data}}
{{#if n === ../n2 * 5}}
{{n + 10.1}}
{{/if}}
{{/each}}

Corresponding abstract syntax tree:

Translation Code

You can then use the visitor mode to write the logic of the generated code to the visitor object, traversing the AST to convert the corresponding subtree or node into JavaScript code.

This step can continue gracefully using code templates to replace the code template's data with the corresponding JavaScript unit of the template. But in order not to torture the brain, finally relax, you can directly use the original code splicing:

visitor.tplNode=function(node){

    if(node.escapeHTML){
        codes.push("if("+node.id+" in data) { ret.push(KISSY.escapeHTML(data."+node.js+");) }"+
        " else { KISSY.warn("not found")!; }");
    }else{
    }

};

But it was a torture.

Offline compilation

Most DSLs are recommended for conversion to the target language before use, and the client can compile online when the end-user is not too concerned with performance.

Xtemplate through the kissy-xtemplate command support to compile the template code offline as a template function module, so that the client can directly require the module, eliminating the client-side compilation process, while developing directly face HTML similar template code, Eliminates the tedious character of string embedding templates.

such as t-tpl.html

{{ offline }} compile

Run

kissy-xtemplate -t t-tpl.html -m tests/t -w

Can get T.js

KISSY.add("tests/t",function(){
    function render(data){
    }
    return render;
});

One drawback of off-line compilation is that the compiled code is certainly much larger than the native template, which is also a reflection of the DSL-saving code, readable features (the code must be unreadable).

Next

There are two major problems:

Large Size

Compressed before 130k, but after gzip+compress due to the generation of more repetitive code, to 10k, but still need to optimize the build code: Reduce the template parser code. You can also optimize the size of the template into the final code, which is useful for offline compilation.

xtemplate module needs splitting

When you choose to compile offline, actually Xtemplate's compiled code can be split into two modules: Xtemplate/runtime and Xtemplate/compiler without downloading. This allows the functional infrastructure to load the template directly with Xtemplate/runtime when you choose to compile offline.

Xtemplate Document

Api

Demo

Tutorial

Recommended Books

Thanks to these authors, without these books, this task cannot be accomplished

Compilers:principles,techniques and Tools

DSL in Action

Language implementation Patterns:create Your OWN domain-specific and general programming Languages

Thanks

In the development process, refer to the following tools:

Velocity

Closure templates

Bison

Jison

Handlebar

Mustache



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.