1

I am trying to get a handle on jison, which is a javascript implementation of Bison. My specific language I am trying to parse looks like this:

foo(10)
bar()
foo(20)
baz()

I want to parse this into something like:

return [
  { func: 'foo', arg: 10 },
  { func: 'bar' },
  { func: 'foo', arg: 20 },
  { func: 'baz' }
]

So far, my jison definition looks like this:

var grammar = {
  'lex': {
    'rules': [
      ['\\s+', '/* skip whitespace */'],
      ['[0-9]+\\b', 'return "INTEGER";'],
      ['\\(', 'return "OPEN_PAREN"'],
      ['\\)', 'return "CLOSE_PAREN"'],
      ['[\\w]+\\s*(?=\\()', 'return "FUNC_NAME"'],
      ['$', 'return "LINE_END"']
    ]
  },

  'bnf': {
    "expression": [["e LINE_END", "return $1;"]],
    "e": [
      ["FUNC_NAME OPEN_PAREN INTEGER CLOSE_PAREN", "$$ = { func: $1, arg: $3 };"],
      ["FUNC_NAME OPEN_PAREN CLOSE_PAREN", "$$ = { func: $1 };"]
    ]
  }
};

When I run this, I get this error:

Error: Parse error on line 1:
forward(10)turnLeft()forward(2
-----------^
Expecting 'LINE_END', got 'FUNC_NAME'
    at Parser.parseError (eval at createParser (/Users/user/project/node_modules/jison/lib/jison.js:1327:13), <anonymous>:30:21)
    at Parser.parse (eval at createParser (/Users/user/project/node_modules/jison/lib/jison.js:1327:13), <anonymous>:97:22)
    at Object.<anonymous> (/Users/user/project/generate-parser.js:39:20)
    at Module._compile (module.js:660:30)
    at Object.Module._extensions..js (module.js:671:10)
    at Module.load (module.js:573:32)
    at tryModuleLoad (module.js:513:12)
    at Function.Module._load (module.js:505:3)
    at Function.Module.runMain (module.js:701:10)
    at startup (bootstrap_node.js:193:16)

Clearly, I am not understanding something to do with line endings separating individual statements. I've looked at the examples for jison and I've read and re-read the Bison docs but still do not fully understand the "Semantic Actions" aspect.

What am I missing here? In my mind, I have defined e in two terminal forms, and the nonterminal form e LINE_END.

Any help would be greatly appreciated, thanks!

AndyPerlitch
  • 4,539
  • 5
  • 28
  • 43
  • 1
    So where (in your mind) have you specified that an input can consist of *multiple* expressions? Jison/bison grammars (grammars in general, in fact) do not feature implicit syntax. To me --and jison -- your grammar allows a single expression, and whatever follows is thus taken to be ungrammatical. – rici Feb 04 '18 at 16:30
  • You are right, I have not been explicit about multiple expressions, and it makes sense that this would be the problem... I suppose thats what I have been trying to find an example of. – AndyPerlitch Feb 04 '18 at 16:36
  • 2
    You need to add a recursive production: `expressions: expression | expressions expression;`. And you might want to add `expression: LINE_END` so that the user can enter blank lines. – rici Feb 04 '18 at 16:47
  • Also, the regex for a newline is `\n`, not `$`. `$` is a zero-width assertion, so it doesn't actually match the newline character. The newline will instead be matched by the `\s+` pattern, and therefore be ignored. – rici Feb 04 '18 at 16:50
  • w.r.t. `\n` and not `$`, thanks for the clarification. I originally had it as `\n` because I initially assumed zero-width was no good. As for your comment regarding `expressions: expression | expressions` and `expression: LINE_END`: Conceptually I think I fully understand, but now my struggle is how that actually translates into the JSON itself. Will it be in the `rules` or the `bnf` section? Sorry for the cluelessness... tryin my best :-/ – AndyPerlitch Feb 04 '18 at 16:59
  • thinking more, it cant be in the rules, so its gotta be in the `bnf`, but what would be the "right side" of that, e.g. the second string that starts with `$$` in other spots? – AndyPerlitch Feb 04 '18 at 17:01

0 Answers0