Parser JavaScript w Pythonie [zamknięty]
Istnieje parser JavaScript przynajmniej w C i Javie (Mozilla), w JavaScript (znowu Mozilla) i Ruby. Czy istnieje obecnie coś dla Pythona?
Nie potrzebuję interpretera JavaScript, per se, tylko parsera zgodnego ze standardami ECMA-262.
Szybkie wyszukiwanie w google nie ujawniło żadnych natychmiastowych odpowiedzi, więc pytam społeczność SO.
5 answers
ANTLR, inne narzędzie do rozpoznawania języków, jest narzędziem językowym, które zapewnia ramy do konstruowania rozpoznawaczy, tłumaczy, kompilatorów i tłumaczy z opisów gramatycznych zawierających działania w różnych językach docelowych.
Strona ANTLR zawiera wiele gramatyk , w tym jeden dla JavaScript .
Tak się składa, że jest dostępne API Pythona - można więc wywołać generowany lexer (rozpoznawacz) z gramatyki bezpośrednio z Pythona (powodzenia).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-29 07:15:54
Obecnie istnieje co najmniej jedno lepsze narzędzie, zwane slimit
:
SlimIt to minifier JavaScript napisany w Pythonie. Kompiluje JavaScript w bardziej kompaktowy kod, dzięki czemu pobiera i uruchamia szybciej.
SlimIt zapewnia również bibliotekę, która zawiera Parser JavaScript, lexer, Ładna drukarka i gość z drzewa.
Demo:
Wyobraź sobie, że mamy następujący kod javascript:
$.ajax({
type: "POST",
url: 'http://www.example.com',
data: {
email: '[email protected]',
phone: '9999999999',
name: 'XYZ'
}
});
And now We need to get email
, phone
i name
wartości z obiektu data
.
Ideą byłoby utworzenie instancji parsera slimit
, odwiedzenie wszystkich węzłów, filtrowanie wszystkich przypisań i umieszczenie ich w słowniku:
from slimit import ast
from slimit.parser import Parser
from slimit.visitors import nodevisitor
data = """
$.ajax({
type: "POST",
url: 'http://www.example.com',
data: {
email: '[email protected]',
phone: '9999999999',
name: 'XYZ'
}
});
"""
parser = Parser()
tree = parser.parse(data)
fields = {getattr(node.left, 'value', ''): getattr(node.right, 'value', '')
for node in nodevisitor.visit(tree)
if isinstance(node, ast.Assign)}
print fields
Drukuje:
{'name': "'XYZ'",
'url': "'http://www.example.com'",
'type': '"POST"',
'phone': "'9999999999'",
'data': '',
'email': "'[email protected]'"}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-04 05:09:39
Jak wspomniano pib, pynarcissus jest tokenizerem Javascript napisanym w Pythonie. Wydaje się, że ma kilka szorstkich krawędzi, ale do tej pory działa dobrze na to, co chcę osiągnąć.
Aktualizacja: zrobiłem kolejny crack na pynarcissus i poniżej jest kierunek pracy dla korzystania z PyNarcissus w systemie wzorca odwiedzającego. Niestety mój obecny klient kupił kolejną iterację moich eksperymentów i postanowił nie podawać jej do wiadomości publicznej. Czystszą wersją poniższego kodu jest na gist Tutaj
from pynarcissus import jsparser
from collections import defaultdict
class Visitor(object):
CHILD_ATTRS = ['thenPart', 'elsePart', 'expression', 'body', 'initializer']
def __init__(self, filepath):
self.filepath = filepath
#List of functions by line # and set of names
self.functions = defaultdict(set)
with open(filepath) as myFile:
self.source = myFile.read()
self.root = jsparser.parse(self.source, self.filepath)
self.visit(self.root)
def look4Childen(self, node):
for attr in self.CHILD_ATTRS:
child = getattr(node, attr, None)
if child:
self.visit(child)
def visit_NOOP(self, node):
pass
def visit_FUNCTION(self, node):
# Named functions
if node.type == "FUNCTION" and getattr(node, "name", None):
print str(node.lineno) + " | function " + node.name + " | " + self.source[node.start:node.end]
def visit_IDENTIFIER(self, node):
# Anonymous functions declared with var name = function() {};
try:
if node.type == "IDENTIFIER" and hasattr(node, "initializer") and node.initializer.type == "FUNCTION":
print str(node.lineno) + " | function " + node.name + " | " + self.source[node.start:node.initializer.end]
except Exception as e:
pass
def visit_PROPERTY_INIT(self, node):
# Anonymous functions declared as a property of an object
try:
if node.type == "PROPERTY_INIT" and node[1].type == "FUNCTION":
print str(node.lineno) + " | function " + node[0].value + " | " + self.source[node.start:node[1].end]
except Exception as e:
pass
def visit(self, root):
call = lambda n: getattr(self, "visit_%s" % n.type, self.visit_NOOP)(n)
call(root)
self.look4Childen(root)
for node in root:
self.visit(node)
filepath = r"C:\Users\dward\Dropbox\juggernaut2\juggernaut\parser\test\data\jasmine.js"
outerspace = Visitor(filepath)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-15 08:48:26
Przetłumaczyłem esprimę.js do Pythona:
Https://github.com/PiotrDabkowski/pyjsparser
Jest to tłumaczenie ręczne, więc jego bardzo szybkie, zajmuje około 1 sekundy, aby przetworzyć plik angular.js
(więc 100k znaków na sekundę). Obsługuje cały ECMAScript 5.1 oraz części wersji 6 - na przykład funkcje strzałek, const
, let
.
Alternatywnie możesz użyć automatycznego tłumaczenia nowszej wersji esprimy do Pythona, który działa świetnie i obsługuje całe JavaScript 6!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-10 22:59:41
Możesz spróbować python-spidermonkey Jest to wrapper nad spidermonkey, który jest nazwą kodową dla implementacji JavaScript w języku C Mozilli.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-24 09:39:05