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.

Basic question: how to best handle this case

See original GitHub issue

Hi there, I have a very simple DSL that I’m writing a parser for. However, I’m having trouble coming up with an elegant solution.

The DSL looks like this:

foo
foo or bar
foo or bar or baz
(foo or bar) and baz

So the pattern is (ignoring nested expressions and assuming all tuples are of size 1 or 2):

const word = regex(/.*/)
const separator = alt(
  string('or'),
  string('and')
)
const expression = alt(
  seq(word, separator, word),
  word
)

However, word also matches or and and! Words can contain numbers, spaces, and special characters, so I can’t just make the regex more specific. What I ended up doing was adding a negative lookahead to the regex: (?! and )(?! or ).

Is there a more elegant way to express this, without resorting to negative lookaheads?

Thanks!

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:7

github_iconTop GitHub Comments

1reaction
wavebeemcommented, Oct 4, 2016

Something like this might be useful to you:

var util = require("util")
var P = require("parsimmon")
var _ = P.whitespace

function spaced(parser) {
  return _.then(parser).skip(_)
}

var Word =
  P.regex(/[^ ]+/).chain(w =>
    w === "and" || w === "or"
      ? P.fail("a word")
      : P.of({type: "string", value: w}))

var Phrase =
  P.sepBy1(Word, _).map(words => ({type: "phrase", words}))

var Connector =
  spaced(P.string("and").or(P.string("or")))

var ConnectedExpression =
  P.lazy(() => P.alt(
    P.seqMap(Phrase, Connector, ConnectedExpression, (l, m, r) =>
      ({connector: m, left: l, right: r})
    ),
    Phrase
  ))

var src = "foo bar and quux da$"
var res = ConnectedExpression.parse(src)
if (res.status) {
  console.log(util.inspect(res.value, {depth: null, colors: "auto"}))
} else {
  console.error(P.formatError(src, res))
}

Output

{ connector: 'and',
  left:
   { type: 'phrase',
     words:
      [ { type: 'string', value: 'foo' },
        { type: 'string', value: 'bar' } ] },
  right:
   { type: 'phrase',
     words:
      [ { type: 'string', value: 'quux' },
        { type: 'string', value: 'da$' } ] } }

If that looks useful, feel free to ask questions and I can dive into more detail later.

0reactions
wavebeemcommented, Oct 4, 2016

You’re welcome! Best of luck on your parser.

Read more comments on GitHub >

github_iconTop Results From Across the Web

10 Case Interview Question Examples (Plus Tips on ... - Indeed
The following are 10 examples of case interview questions. You can use these examples to get a better understanding of how case interview ......
Read more >
How to Solve a Case Study – A Structured Approach
1. Restate the question and make sure you understand the problem statement by confirming with the interviewer · 2. Clarify the goals ·...
Read more >
Case Interview Questions - MConsultingPrep
There are the four basic steps to answer case interview questions: •Step 1: Clarify any unclear points in the question. •Step 2: Announce...
Read more >
100 Case Study Interview Questions [Updated for 2020]
A good case study is designed to build trust. Ask clients to describe the tools and processes they used before your product or...
Read more >
10 Common Job Interview Questions and How to Answer Them
How do you deal with pressure or stressful situations? ... When you answer this question, highlight the best traits of your personality and ......
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