Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change state on specifik keyword Token. #115

Open
JulianKK opened this issue Jan 7, 2019 · 3 comments
Open

Change state on specifik keyword Token. #115

JulianKK opened this issue Jan 7, 2019 · 3 comments
Labels

Comments

@JulianKK
Copy link

JulianKK commented Jan 7, 2019

Is it possible to Call next:stage when a keyword was metched?

@tjvr
Copy link
Collaborator

tjvr commented Jan 7, 2019

I'm afraid not!

But you can manually call lexer.setState after you see that keyword 🙂

Sent with GitHawk

@tjvr tjvr added the question label Jan 10, 2019
@evanpurkhiser
Copy link
Contributor

Is there a simple way to do the manual setState call when using moo with nearley? 😉

@evanpurkhiser
Copy link
Contributor

Here was my solution :)

const word = {
  match: /[^\s\n:]+:?/,
  type: moo.keywords({ filter })
};

const space = {
  match: /\s+/,
  lineBreaks: true
};

// Our lexer generates word and space tokens when in it's `main` state. A
// `filter` keyword may be produced by a matching word, in which case we move
// into the `keyValue` state.
//
// A `value` or `boolean` may be matched in the keyValue state, along with
// words and spaces. Any match here will return to the main state.

const lexer = moo.states({
  main: { word, space },
  keyValue: {
    value: { match: /"(?:\\["\\]|[^\n"\\])*"/, pop: 1 },
    boolean: { match: /(?:1|0)/, pop: 1 },
    word: { ...word, pop: 1 },
    space: { ...space, pop: 1 }
  }
});

// NOTE: There is currently no way to push state with moo when a keyword is
// matched [0]. We need to move to the `keyValue` lexer state after matching a
// filter, so we will patch the `next` function to push this state for us.
//
// [0]: https://github.com/no-context/moo/issues/115
const nextFn = lexer.next;

lexer.next = () => {
  const rv = nextFn.apply(lexer);

  if (rv && rv.type === "filter") {
    // TODO(ts): This method is missing from the type definitions. We can
    // remove the any cast when [0] is merged.
    //
    // [0]: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/43477
    (lexer as any).pushState("keyValue");
  }

  return rv;
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants