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

Get name of node #4

Closed
donkeyDau opened this issue Oct 5, 2019 · 5 comments
Closed

Get name of node #4

donkeyDau opened this issue Oct 5, 2019 · 5 comments

Comments

@donkeyDau
Copy link

I'm trying to write a Visitor for the jsleri tree which is returned after parsing. But I got stuck by identifying the exact item. At the moment I get the type (Token, Regex, ...) but not the "name" of the item. Using pyleri the nodes in the tree have names which can easily be accessed by node.element.name. Is the same somehow possible for jsleri? Or do I miss somenthing obvious?

@joente
Copy link
Member

joente commented Oct 6, 2019

Good point, but unfortunately the "name" of the element is not set. There are "onEnter"/"onExit" calls which could be set to each element although I'm not sure that is what you want.

To set the element names, we could implement something like this:

// just as a test, maybe we can make the Grammar constructor to do something
// like this while still being backwards compatible
let setNames = grammar => {
    Object.getOwnPropertyNames(grammar).forEach(name => {
        if (grammar[name] instanceof Jsleri) {
            grammar[name].name = name;
        }
    })
    return grammar;
}

class TestGrammar extends Grammar {
    static kwHi = Keyword('Hi');
    static kwJsleri = Keyword('Jsleri')
    static START = Sequence(this.kwHi, this.kwJsleri);
}

let testGrammar = new (setNames(TestGrammar));

let res = testGrammar.parse('Hi Jsleri')

console.log(res.tree.children[0].element);
// Sequence { args: [..], elements: [..], name: 'START' }

console.log(res.tree.children[0].children[0].element);
// Keyword { args: [ 'Hi' ], keyword: 'Hi', ignCase: false, name: 'kwHi' }

console.log(res.tree.children[0].children[1].element);
// Keyword { args: [ 'Jsleri' ], keyword: 'Jsleri', ignCase: false, name: 'kwJsleri' }

@donkeyDau
Copy link
Author

donkeyDau commented Oct 7, 2019

Thank you. That looks exactly what I'm looking for. Unfortunately it seems like babel is not able to work with static properties:

./src/lib/parseCommand.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: Unexpected token (11:21)

   9 | 
  10 | class MyGrammar extends jsleri.Grammar {
> 11 |   static tParentOpen = jsleri.Token(\'(\', \'tParentOpen\');
     |                      ^
  12 |   static tParentClose = jsleri.Token(\')\', \'tParentClose\');
  13 |   static tCurlyOpen = jsleri.Token(\'{\', \'tCurlyOpen\');
  14 |   static tCurlyClose = jsleri.Token(\'}\', \'tCurlyClose\');

BabelLoaderError: SyntaxError: Unexpected token (11:21)

   9 | 
  10 | class MyGrammar extends jsleri.Grammar {
> 11 |   static tParentOpen = jsleri.Token(\'(\', \'tParentOpen\');
     |                      ^
  12 |   static tParentClose = jsleri.Token(\')\', \'tParentClose\');
  13 |   static tCurlyOpen = jsleri.Token(\'{\', \'tCurlyOpen\');
  14 |   static tCurlyClose = jsleri.Token(\'}\', \'tCurlyClose\');

    at transpile (/app/packages/datawrangler/node_modules/babel-loader/lib/index.js:65:13)
    at Object.module.exports (/app/packages/datawrangler/node_modules/babel-loader/lib/index.js:173:20)

I got around this by defining the Tokens/Keywords/... in the constructor. But then they are not available as Properties, right?

@donkeyDau
Copy link
Author

This question on stackOverFlow is dealing with this problem: https://stackoverflow.com/questions/40367392/static-class-property-not-working-with-babel

I'm still using babel 6.x.y But the transform-class-properties plugin requires babel >= 7.0.0. Maybe I find another way around this babel issue...

But besides that: @joente Your proposal looks exactly what I was looking for. Wouldn't it be nice to push that to the master?

@joente
Copy link
Member

joente commented Oct 7, 2019

It probably will work with any Object so I don't think you need to use a class with static class properties.

I think something like this will work (but i did not test the code)

let myGrammar = {};
myGrammar.kwHi = Keyword('Hi');
myGrammar.kwJsleri = Keyword('Jsleri');
myGrammar.START = Sequence(myGrammar.kwHi, myGrammar.kwJsleri);

let compiled = new Grammar(setNames(myGrammar).START);
...

Anyway, I will do some testing, and hope to spend a little time on this issue on Wednesday and merge a working solution to master.

joente pushed a commit that referenced this issue Oct 16, 2019
@joente
Copy link
Member

joente commented Oct 16, 2019

Published version 1.1.9 which sets the element names when creating a grammar. (either when using a class or a simple object)

@joente joente closed this as completed Oct 16, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants