0

I'm playing with PEG.js and reading and in the Nathans University i found a good "explain" how to build my own languaje but i'm stuck with this step

i dont understand the primary can explain me please

start =
    comma

comma = 
    left: additive "," right:comma 
        { return {tag: ",", left:left, right:right}; }
    / additive

additive =
    left:multiplicative "+" right:additive
        { return {tag: "+", left:left, right:right}; }
  / multiplicative

multiplicative =
    left:primary "*" right:multiplicative
        { return {tag: "*", left:left, right:right}; }
  / primary

primary =
    integer
  / "(" comma:comma  ")" # Can explain me why is necesary "(" and ")"
      { return comma; }

integer =
    digits:[0-9]+
        { return parseInt(digits.join(""), 10); }

test

var parse = wrapExceptions(PEG.buildParser(answer).parse);

assert_eq(parse("1+2"),
    {tag:"+", left:1, right:2},
    "parse 1+2");
assert_eq(parse("1+2*3"),
    {tag:"+", left:1, right:{tag:"*", left:2, right:3}},
    "parse 1+2*3");
assert_eq(parse("1,2"),
    {tag:",", left:1, right:2},
    "parse 1,2");
assert_eq(parse("1,2+3"),
    {tag:",", left:1, right:{tag:"+", left:2, right:3}},
    "parse 1,2+3");
assert_eq(parse("1*2,3"),
    {tag:",", left:{tag:"*", left:1, right:2}, right:3},
    "parse 1*2,3");

my question is why is necesary the / "(" comma:comma ")" if the entry does not have parenthesis, if remove that line the last test fails

rkmax
  • 17,633
  • 23
  • 91
  • 176
  • This may be obvious, but `primary` is either an `integer` or a `comma` surrounded by `()`s. What is exactly your doubt? – acdcjunior Nov 05 '13 at 04:29

1 Answers1

0

The line in question is the first part of an alternative expression, for the primary rule -- it is tested only if integer does not match.

This alternate expression starts after the / and includes the corresponding action block: { return comma; }

Note that "comma" is being used in two distinct ways here -- both as a rule name and also as a label identifier. See PEG.js - Parsing Expression Types:

label : expression

Match the expression and remember its match result under given label. The label must be a JavaScript identifier. ...

So, integer / "(" comma:comma ")" first attempts to match integer; if that fails it then attempts to match the entire second expression.

The label could be any valid JavaScript identifier. Please consider the following snippet, which is functionally-equivalent to your example:

primary =
    integer
  / "(" result:comma ")"
      { return result; }

If parenthesis are not relevant then you could omit the entire second expression, leaving just:

primary =
    integer

As another quick example of labeling, this would also work (but is redundant):

primary =
    anumber:integer
      { return anumber; }
humbletim
  • 1,128
  • 11
  • 10
  • if you remove the ` / "(" comma:comma ")"` line the sample dont work – rkmax Nov 05 '13 at 06:33
  • correct; think of the two lines after the ```/``` like ```function(comma) { return comma; }```. you are only removing the ```function(comma)``` part -- and apparently leaving behind the trailing, related ```{ return comma; }``` part? if you remove the line in question, you must also remove the related action... – humbletim Nov 05 '13 at 21:31