+ All Categories
Home > Software > Interpreter Design Pattern in Javascript

Interpreter Design Pattern in Javascript

Date post: 16-Apr-2017
Category:
Upload: dmytro-verbovyi
View: 318 times
Download: 0 times
Share this document with a friend
20
eleks.com Interpreter Pattern Design Patterns Program by Dmytro Verbovyi
Transcript

eleks.com

Interpreter Pattern

Design Patterns Program

by Dmytro Verbovyi

IntroductionGiven a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language. (GOF) ***

***The basic idea is to have a class for each symbol(terminal or nonterminal) in a specialized computer language.

● Frequent changing task

● Queries, terms and expression

● Regular expressions

● Sentences in the language represented as abstract syntax trees (AST)

● Easy to extend and modify grammar. (Classes implementation that describes abstract syntax nodes easily coded)

● You can easily change the method of calculating expressions

Problem solving

Real world example - Barcode

How Barcode works - BNF notation

● <UPC>::=<Manufacture ID><Item Number><Check Digit>● <Manufacture Id>::=<Digit><Digit><Digit><Digit><Digit><Digit>● <Item Number>::=<Digit><Digit><Digit><Digit><Digit>● <Check Digit>::=<Digit>● <Digit>::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

Scheme

Implemented example - BNF● <TRAILER>::=<Goods><sPackage><Goods><bPackage><Goods><Goods>● <sPackage>::=<Goods><Goods>● <bPackage>::=<Goods><Goods><Goods><Goods>● <Goods>::= <Table> | <Bed> | <TV> | <LapTop>

Language sentence<script type="text/template" id="contextTpl"> <h1>{Table}{SPackage}{Bed}{BPackage}{TV}{LapTop}</h1></script>

Abstract Expression//Abstract Expressionclass Goods { constructor(){ this.name = this.__proto__.constructor.name; } interpret(context) { return this.name + ': ' + context.getPrice(this.name) + '<br>'; }}

Terminal Expressions

//Terminal Expressionsclass TV extends Goods {}

class LapTop extends Goods {}

class Table extends Goods {}

class Bed extends Goods {}

Nonterminal Expressions//Non-Terminal Expresionsclass SPackage extends Goods { constructor() { super(); this.itemsList = [].slice.call(arguments); } add(item) { this.itemsList.push(item); } interpret(context) { let output = ''; this.itemsList.forEach((exp)=> { output += exp.interpret(context); }); return output; }}

class BPackage extends SPackage {}

Contextclass PriceContext { constructor(bed, table, tv, laptop, sPackage, bPackage) { this.bed = bed; this.table = table; this.tv = tv; this.laptop = laptop; this.spackage = sPackage; this.bpackage = bPackage;

this.prices = {}; } setPrice(prices) { for(let key in prices) { if(!prices.hasOwnProperty(key)) continue;

this.prices[key] = prices[key]; } }

getPrice(name) {

return this.prices[name];

}

interpret(expName){

return

this[expName].interpret(this);

}

}

View - slide 1class View { constructor(el, tplId) { this.el = el; this._vars = {}; this.setTemplate(tplId); } setTemplate(tplId) { this.template = document.getElementById(tplId).innerHTML.replace(/\s/g, ''); } getVars() { let regex = /\{(.*?)\}/g, matches, expressions = []; while (matches = regex.exec(this.template)) { expressions.push(matches[1]); } return expressions; }

View - slide 2render(priceContext) { let output = this.template, vars = this.getVars(); vars.forEach((variable)=> { let expName = variable.toLowerCase(), re = new RegExp("\{" + variable + "\}", 'g');

output = output.replace(re, priceContext.interpret(expName)); });

this.el.innerHTML = output;

return this; }}

Usageconst Main = () => { let el = document.body; let view = new View(el, 'contextTpl');

let smallPackage = new SPackage(); smallPackage.add(new TV()); smallPackage.add(new LapTop());

let bigPackage = new BPackage(); bigPackage.add(new Table()); bigPackage.add(new Bed()); bigPackage.add(new Bed()); bigPackage.add(new TV());

let priceContext = new PriceContext(

new Bed(),

new Table(),

new TV(),

new LapTop(),

smallPackage,

bigPackage

);

priceContext.setPrice({

'Bed': 400,

'TV': 200,

'LapTop': 500,

'Table': 50

});

view.render(priceContext);

};

Sentence and Output

Table: 50TV: 200LapTop: 500Bed: 400Table: 50Bed: 400Bed: 400TV: 200TV: 200LapTop: 500

<script type="text/template" id="contextTpl"> <h1>{Table}{SPackage}{Bed}{BPackage}{TV}{LapTop}</h1></script>

Advantages

Disadvantages

● You have a simple language to interpret

● You can easily change the method of calculating expressions

● You can represent sentences in the language as abstract syntax trees (AST).

● Difficult to support the grammar with a large number of rules

● Each class on each expression

Related Patterns

● Composite for same proccessing terminal and non-terminal expressions

● Flyweight for sharing terminal expressions

● Iterator for traversing the nodes of non-terminals

Inspired by Technology.Driven by Value.

Have a questions?


Recommended