69 votes

Analyseur JavaScript en Python

Il y a un analyseur JavaScript au moins en C et Java (Mozilla), en JavaScript (Mozilla encore) et Ruby. Y en a-t-il actuellement pour Python?

Je n'ai pas besoin d'un interpréteur JavaScript, en soi, juste un analyseur répondant aux normes ECMA-262.

Une recherche rapide sur Google n'a révélé aucune réponse immédiate, je demande donc à la communauté SO.

50voto

alecxe Points 50783

De nos jours, il existe au moins un meilleur outil, appelé slimit:

SlimIt est un JavaScript minifier écrit en Python. Il compile Le code JavaScript en code plus compact, afin qu'il télécharge et exécute plus rapide.

SlimIt fournit également une bibliothèque qui comprend un parser JavaScript, lexer, assez imprimante et un arbre visiteur.

Démo:

Imaginons que nous ayons le code javascript suivant:

$.ajax({
    type: "POST",
    url: 'http://www.example.com',
    data: {
        email: 'abc@g.com',
        phone: '9999999999',
        name: 'XYZ'
    }
});

Et maintenant, nous devons obtenir de l' email, phone et name des valeurs de l' data objet.

L'idée ici serait de l'instancier un slimit de l'analyseur, visiter tous les nœuds, filtre tous les travaux et de les mettre dans le dictionnaire:

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: 'abc@g.com',
        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

Il imprime:

{'name': "'XYZ'", 
 'url': "'http://www.example.com'", 
 'type': '"POST"', 
 'phone': "'9999999999'", 
 'data': '', 
 'email': "'abc@g.com'"}

24voto

gimel Points 30150

ANTLR, un Autre Outil pour la Reconnaissance de la Langue, est un outil de langue qui fournit un cadre pour construire des modules de reconnaissance, des interprètes, des compilateurs et des traducteurs de l'grammaticales, descriptions contenant des actions dans une variété de langues cibles.

Le ANTLR site fournit de nombreuses grammaires , y compris un pour JavaScript.

Comme il arrive, il y a une API Python disponibles de sorte que vous pouvez appeler l'analyseur lexical (de reconnaissance) généré à partir de la grammaire directement à partir de Python (bonne chance).

10voto

David Points 5710

Comme frp mentionné, pynarcissus est un Javascript tokenizer écrit en Python. Il semble avoir des bords rugueux mais jusqu'à présent, a été fonctionne bien pour ce que je veux accomplir.

Mise à jour: il a Pris une autre fissure à pynarcissus et ci-dessous est un sens de travail pour l'utilisation de PyNarcissus dans un modèle visiteur comme système. Malheureusement, mon client a acheté la prochaine itération de mes expériences, et ont décidé de ne pas le rendre public source. Une version plus propre de le code ci-dessous sur l'essentiel ici

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)

7voto

pib Points 2010

http://code.google.com/p/pynarcissus/ semble avoir un analyseur. Je ne sais pas dans quel état il se trouve, mais il semble être complet.

2voto

swamy Points 129

Vous pouvez essayer python-spidermonkey C'est un wrapper sur spidermonkey qui est le nom de code pour l'implémentation C de Mozilla en javascript.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X