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

Lose "()" after parse and cause Syntax error in js #114

Open
forthlsss opened this issue Jun 4, 2020 · 3 comments
Open

Lose "()" after parse and cause Syntax error in js #114

forthlsss opened this issue Jun 4, 2020 · 3 comments

Comments

@forthlsss
Copy link

forthlsss commented Jun 4, 2020

here is a content:

function _fAddItem(_aoContainer, _aoItem, _anIndex)
{
({}).toString.call([]) != "[object Array]" && (_aoItem = [_aoItem]);
return _aoContainer.slice(0, _anIndex).concat(_aoItem).concat(_aoContainer.slice(_anIndex, _aoContainer.length));
};

and this is my code

from slimit.parser import Parser
parser = Parser()
tree = parser.parse(content)
print tree.to_ecma()

and then i got this

function _fAddItem(_aoContainer, _aoItem, _anIndex) {
{
}.toString.call([]) != "[object Array]" && (_aoItem = [_aoItem]);
return _aoContainer.slice(0, _anIndex).concat(_aoItem).concat(_aoContainer.slice(_anIndex, _aoContainer.length));
}
;
I found that the "()" in the "({}}"" in line 3 of the content is gone and casued Syntax error in js
i wonder which part of code what reason caused this.
I have not learned lexer, parser or something,i want to know whether i have the ability to learn and fix it by myself or not ,and if it will takes me too much time.
I will be appreciate if someone can help

@metatoaster
Copy link

The package calmjs.parse, a fork of slimit I have created, will correctly parse the grouping operator (the cause of the problem here in slimit). Following is a similar example using calmjs.parse:

>>> content = '''function _fAddItem(_aoContainer, _aoItem, _anIndex)
... {
... ({}).toString.call([]) != "[object Array]" && (_aoItem = [_aoItem]);
... return _aoContainer.slice(0, _anIndex).concat(_aoItem).concat(_aoContainer.slice(_anIndex, _aoContainer.length));
... };'''
>>> from calmjs.parse import es5
>>> tree = es5(content)
>>> print(tree)
function _fAddItem(_aoContainer, _aoItem, _anIndex) {
  ({}).toString.call([]) != "[object Array]" && (_aoItem = [_aoItem]);
  return _aoContainer.slice(0, _anIndex).concat(_aoItem).concat(_aoContainer.slice(_anIndex, _aoContainer.length));
}
;

@forthlsss
Copy link
Author

The package calmjs.parse, a fork of slimit I have created, will correctly parse the grouping operator (the cause of the problem here in slimit). Following is a similar example using calmjs.parse:

>>> content = '''function _fAddItem(_aoContainer, _aoItem, _anIndex)
... {
... ({}).toString.call([]) != "[object Array]" && (_aoItem = [_aoItem]);
... return _aoContainer.slice(0, _anIndex).concat(_aoItem).concat(_aoContainer.slice(_anIndex, _aoContainer.length));
... };'''
>>> from calmjs.parse import es5
>>> tree = es5(content)
>>> print(tree)
function _fAddItem(_aoContainer, _aoItem, _anIndex) {
  ({}).toString.call([]) != "[object Array]" && (_aoItem = [_aoItem]);
  return _aoContainer.slice(0, _anIndex).concat(_aoItem).concat(_aoContainer.slice(_anIndex, _aoContainer.length));
}
;

Thank you very much, I tried this method, it works very well.
But i found that after es5(), I got a <class'calmjs.parse.factory.ES5Program'>, and slemit.parser.Parser() got <class'calmjs.parse.factory.ES5Program'>.
This caused some problems because I used a lot of APIs in
slimit.ast in rest of the code.Mainly some type judgments such as if isinstance(node, ast.Default).
So it can't fit now.
I browsed calmjs.parse.asttypes but they are some differences.
Is there a good solution to this problem? Or do I have to modify my code for calmjs.Thanks again.

@metatoaster
Copy link

metatoaster commented Jun 4, 2020

The calmjs.parse.asttypes module originated from slimit.ast, although there are certain differences between certain classes as there were small amounts of assumptions made in slimit that does not reflect the actual ECMA-262 5.1 specification (most notably with switch/default/case statements and issue like this with the grouping operator). Given how something like if isinstance(node, ast.Default) is used, here is an example of how one might walk through the AST to get Default nodes:

from calmjs.parse import es5
from calmjs.parse import asttypes as ast
from calmjs.parse.walkers import Walker

tree = es5(source)
walker = Walker()
for node in walker.filter(tree, lambda node: isinstance(node, ast.Default)):
    print(node)  # just print them out as a demo

Otherwise the "visitor" pattern that slimit uses mostly works, aside from the renamed classes, such as Program -> ES5Program as mentioned; new classes introduced in calmjs.parse such as the GroupingOp class (that was source of the issue just experienced here in slimit) may need to be handled. Another project (js2xml) has made a successful switch from slimit to calmjs.parse and the changes to the visitor appears to be rather minimal. Hopefully this level of work is also limited in scope for your project, should you decide to make this change.

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