question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add something like `=+` to match the existing `+=`

See original GitHub issue

Currently, += prepends a PEG to the supergrammar’s rule.

We have been building a parser that uses inheritance to extend a grammar with error recovery productions, and find ourselves wishing for something like a =+ that appends to the supergrammar’s rule:

SomeNT =+ SomeErrorRecoveryPEG
// ... would be nice if it expanded to...
SomeNT = Rules | From | The | SuperGrammar | SomeErrorRecoveryPEG

Would a patch implementing a =+ operator be welcome?

Building on this question, if it were considered valuable to have both += and =+, would it make any sense to have += append and =+ prepend?

Finally, if =+ is a bad choice of operator, perhaps |= is a better choice for the appending variant?

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:15 (14 by maintainers)

github_iconTop GitHub Comments

1reaction
pdubroycommented, Dec 27, 2020

Closing this since the super-splice operator has landed. @tonyg, have you had a chance to give this a try?

0reactions
elgertamcommented, Dec 31, 2020

@pdubroy I have been working with @tonyg on the project he mentioned.

I really love the ... syntax! I just tested it out on our parser, and it has cleaned up the one particularly hairy case where we had to copy-paste several lines from the parent grammar into the child grammar.

Unfortunately, most of the candidates for clean up couldn’t be change due to arity checks on the semantics methods.

For example, let a parent grammar be

FooGrammar {
  Foo = Bar+

  Bar = "<" Baz ">"

  Baz = letter+                   -- name
      | digit+ ("." digit+)?      -- number
}

with semantics

const fooSemantics = {
  Foo(bar) {
    return bar.ast();
  },
  Bar(_oBrace, baz, _cBrace) {
    return baz.ast();
  },
  Baz_name(id) {
    return id.sourceString;
  },
  Baz_number(whole, _dot, frac) {
    return parseFloat(this.sourceString);
  }
};

.

I would like to define a child grammar

SonOfFooGrammar <: FooGrammar {
  Bar := ...
       | errorLine   -- error

  Baz := ...
       | (~">" any)+ -- error

  errorLine = nonnl+ (lineTerminator | end)

  nonnl = ~lineTerminator any
  lineTerminator = "\n" | "\r"
}

with semantics

const sonOfFooSemantics = {
  ...fooSemantics,
  Bar_error(_err){
    console.warn(`Parse error: Bar: \`${this.sourceString}\``);
  },
  Baz_error(_err){
    console.warn(`Parse error: Baz: \`${this.sourceString}\``);
  },
};

.

However, because of the arity rules, I have to instead define SonOfFooGrammar as

SonOfFooGrammar <: FooGrammar {
  Bar := "<" Baz ">" -- nonError
       | errorLine   -- error

  Baz := ...
       | (~">" any)+ -- error

  errorLine = nonnl+ (lineTerminator | end)

  nonnl = ~lineTerminator any
  lineTerminator = "\n" | "\r"
}

with semantics

const { Bar: _Bar, ...sonOfFooSemantics } = {
  ...fooSemantics,
  Bar_nonError: fooSemantics.Bar,
  Bar_error(_err){
    console.warn(`Parse error: Bar: \`${this.sourceString}\``);
  },
  Baz_error(_err){
    console.warn(`Parse error: Baz: \`${this.sourceString}\``);
  },
};

.

This isn’t so bad (though I find this usage of ES6’s destructuring assignment to be a bit too clever).

I personally would find it quite elegant for the extension to work as in the former case, though I don’t (yet) know enough about Ohm’s internals to know how feasible this change would be. If there’s no reason why this wouldn’t work, I could begin working on a PR.

Regardless, I love the new super-slice feature and I think it can be quite useful going forward.

I’m also curious about the Schärli-style traits mentioned above. Tony and I had independently discussed something like “traits” for Ohm, and both of us thought a feature like that would be useful.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Excel MATCH function with formula examples - Ablebits
See how to match data in Excel using the MATCH function. Basic uses and advanced formula examples for case-sensitive match, Vlookup and ...
Read more >
Add records to a table by using an append query
This article explains how to create and run an append query. You use an append query when you need to add new records...
Read more >
About keyword matching options - Google Ads Help
The keyword match types dictate how closely the keyword needs to match with the user's search query so that the ad can be...
Read more >
Categorize and match online bank transactions in QuickBooks ...
It looks for and tries to match them with transactions you've already ... For most banks, QuickBooks downloads the latest available transactions every...
Read more >
WHERE - Cypher Manual - Neo4j
WHERE` adds constraints to the patterns in a `MATCH` or `OPTIONAL MATCH` clause or filters ... If you want to compare a property...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found