Skip to content

Deviations From Flex Bison

Sannis edited this page Sep 17, 2012 · 19 revisions

Lex Patterns

Literal tokens

Notice that token "foo" will match whole word only, while ("foo") will match foo anywhere. See issue #63

Longest rule matching

The lexer will use the first rule that matches the input string unless you use %options flex, in which case it will use the rule with the longest match.

Additions

Because Jison uses JavaScript’s regular expression engine, it is possible to use some metacharacters that are not present in Flex patterns.

Negative Lookahead

Flex patterns support lookahead using /, Jison adds negative lookahead using /!.

Advanced Grouping Options

Jison supports as advanced grouping options

  • non-grouping brackets (?:PATTERN),
  • positive lookahead (?=PATTERN) and
  • negative lookahead (?!PATTERN).

yymore, yyless, etc...

Braces in actions

Within lexer actions use %{ ... %} delimiters if you want to use block-style statements, e.g.:

.*  %{
  if (true) {
    console.log('test');
  }
  // ...
%}

Within parser actions use {{ .. }} delimiters for the same purpose:

test
  : STRING EOF  {{
    if (true) {
      console.log('test');
    }
    // ...
    return $1;
  }}
  ;

See issue #85

Semantic Actions

Actions should contain JavaScript instead of C, naturally.

Braces

As of Jison v0.2.8, you no longer need to use double braces.

Short-hand syntax

There is a short-hand arrow syntax:

 exp:    ...
         | '(' exp ')' -> $2
         | exp '+' exp -> $1 + $3

Accessing values and location information

Normally, you’d have to use the position of the corresponding nonterminal or terminal in the production, prefixed by a dollar sign $, e.g.:

 exp:    ...
         | '(' exp ')'
             { $$ = $2; }

Now, you can also access the value by using the name of the nonterminal instead of its position, e.g.:

 exp:    ...
         | '(' exp ')'
             { $$ = $exp; }

If the rule is ambiguous (the nonterminal appears more than once,) append a number to the end of the nonterminal name to disambiguate the desired value:

 exp:    ...
         | exp '+' exp
             { $$ = $exp1 + $exp2; }

Association by name leads to a looser coupling (and is easier to grok.)

This also works for accessing location information:

 exp:    ...
         | '(' exp ')'
             { @$ = @exp; /* instead of @$ = $2 */ }

Extended BNF

Jison now supports EBNF syntax, showcased here.

Clone this wiki locally