Interpreter

The interpreter pattern is an interesting pattern as it allows for the creation of your own language. This might sound like something of a crazy idea, we're already writing JavaScript, why would we want to create a new language? Since the publication of the GoF book Domain specific languages (DSLs) have had something of a renaissance. There are situations where it is quite useful to create a language that is specific to one requirement. For instance the Structured Query Language (SQL) is very good at describing the querying of relational databases. Equally, regular expressions have proven themselves to be highly effective for the parsing and manipulation of text.

There are many scenarios in which being able to create a simple language is useful. That's really the key: a simple language. Once the language gets more complicated, the advantages are quickly lost to the difficulty of creating what is, in effect, a compiler.

This pattern is different from those we've seen to this point as there is no real class structure that is defined by the pattern. You can design your language interpreter however you wish.

Example

For our example let us define a language which can be used to describe historical battles in the land of Westeros. The language must be simple for clerics to write and easy to read. We'll start by creating a simple grammar:

(aggressor -> battle ground <- defender) -> victor

Here you can see that we're just writing out a rather nice syntax that will let people describe battles. A battle between Robert Baratheon and RhaegarTargaryen at the river Trident would look like the following:

(Robert Baratheon -> River Trident <- RhaegarTargaryen) -> Robert Baratheon

Using this grammar we would like to build some code which is able to query a list of battles for answers. In order to do this we're going to rely on regular expressions. For most languages this wouldn't be a good approach as the grammar is too complicated. In those cases one might wish to create a lexor and a parser and build up syntax trees, however, by that point you may wish to re-examine if creating a DSL is really a good idea. For our language the syntax is very simple so we can get away with regular expressions.

Implementation

The first thing we establish is a JavaScript data model for the battle like so:

class Battle {
  constructor(battleGround, agressor, defender, victor) {
    this.battleGround = battleGround;
    this.agressor = agressor;
    this.defender = defender;
    this.victor = victor;
  }
}

Next we need a parser:

class Parser {
  constructor(battleText) {
    this.battleText = battleText;
    this.currentIndex = 0;
    this.battleList = battleText.split("
");
  }
  nextBattle() {
   if (!this.battleList[0])
     return null;
    var segments = this.battleList[0].match(/((.+?)s?->s?(.+?)s?<-s?(.+?)s?->s?(.+)/);
    return new Battle(segments[2], segments[1], segments[3], segments[4]);
  }
}

It is likely best that you don't think too much about that regular expression. However, the class does take in a list of battles (one per line) and using next Battle, allows one to parse them. To use the class we simply need to do the following:

var text = "(Robert Baratheon -> River Trident <- RhaegarTargaryen) -> Robert Baratheon";
var p = new Parser(text);
p.nextBattle()

This will be the output:

{
  battleGround: 'River Trident',
  agressor: 'Robert Baratheon',
  defender: 'RhaegarTargaryen)',
  victor: 'Robert Baratheon'
}

This data structure can now be queried like one would for any other structure in JavaScript.

As I mentioned earlier there is no fixed way to implement this pattern, so the implementation done in the preceding code is provided simply as an example. Your implementation will very likely look very different and that is just fine.

Interpreter can be a useful pattern in JavaScript. It is, however, a pretty infrequently used pattern in most situations. The best example of a language interpreted in JavaScript is the less language that is compiled, by JavaScript, to CSS.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.140.195.225