2008-12-24 8 views
42

में जावास्क्रिप्ट पार्सर जावास्क्रिप्ट (मोज़िला दोबारा) और रूबी में कम से कम सी और जावा (मोज़िला) में एक जावास्क्रिप्ट पार्सर है। क्या पाइथन के लिए वर्तमान में कोई बाहर है?पायथन

मुझे जावास्क्रिप्ट दुभाषिया की आवश्यकता नहीं है, प्रति सी, केवल एक पार्सर जो ईसीएमए -262 मानकों तक है।

एक त्वरित Google खोज ने कोई तत्काल उत्तर नहीं दिया, इसलिए मैं SO समुदाय से पूछ रहा हूं।

उत्तर

16

ANTLR, भाषा मान्यता के लिए एक और उपकरण है कि लक्ष्य पर विभिन्न भाषाओं में कार्रवाई युक्त व्याकरण विवरण से recognizers, दुभाषियों, compilers, और अनुवादकों के निर्माण के लिए एक रूपरेखा प्रदान करता एक भाषा उपकरण है।

ANTLR साइट one for JavaScript सहित कई व्याकरण प्रदान करती है।

जैसा होता है, वहां Python API उपलब्ध है - ताकि आप सीधे पाइथन (शुभकामनाएं) से व्याकरण से उत्पन्न लेक्सर (पहचानकर्ता) को कॉल कर सकें।

+0

यह वही हो सकता है जो मुझे चाहिए, क्योंकि मैं वास्तव में मानक जावास्क्रिप्ट व्याकरण का विस्तार करना चाहता हूं। धन्यवाद! – Claudiu

+23

antlr3 के लिए दोनों ecmascript/जावास्क्रिप्ट व्याकरण टूट गए हैं और अनियमित हैं। यह एक लाल हेरिंग है। –

4

आप python-spidermonkey आज़मा सकते हैं यह spidermonkey पर एक रैपर है जो जावास्क्रिप्ट के मोज़िला के सी कार्यान्वयन के लिए कोडनाम है।

+1

दुर्भाग्य से स्पाइडरमोनकी मृत अपस्ट्रीम है। –

11

जैसा कि पीआईबी उल्लेख किया गया है, pynarcissus पायथन में लिखा गया जावास्क्रिप्ट टोकनेज़र है। ऐसा लगता है कि कुछ मोटे किनारे हैं लेकिन अब तक जो कुछ मैं पूरा करना चाहता हूं उसके लिए अच्छा काम कर रहा हूं।

अपडेटेडः पिनारिसिसस पर एक और दरार ली और नीचे सिस्टम जैसे विज़िटर पैटर्न में PyNarcissus का उपयोग करने के लिए एक कार्यशील दिशा है। दुर्भाग्यवश मेरे वर्तमान ग्राहक ने मेरे प्रयोगों के अगले पुनरावृत्ति को खरीदा और फैसला किया कि इसे सार्वजनिक स्रोत न बनाएं। नीचे दिए गए कोड का एक क्लीनर संस्करण कम से कम एक बेहतर उपकरण है आजकल सार here

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) 
+0

यह जावास्क्रिप्ट एएसटी से जावास्क्रिप्ट को उत्सर्जित नहीं कर सकता है, है ना? मैं एएसटी को संशोधित करना चाहता था और नई जावास्क्रिप्ट को उत्सर्जित करना चाहता था, लेकिन ऐसा लगता है कि ऐसा नहीं हो सकता है। – gsingh2011

+0

@ gsingh2011 नहीं, यह थोड़े से पार्सिंग के साथ संघर्ष कर रहा है, इसलिए दूसरी तरफ से इसकी क्षमताओं के पीछे रास्ता है। – David

30

पर है,, slimit कहा जाता है:

SlimIt एक जावास्क्रिप्ट minifier पायथन में लिखा है। यह जावास्क्रिप्ट को अधिक कॉम्पैक्ट कोड में संकलित करता है ताकि यह तेज़ी से डाउनलोड और चला सके।

स्लिम यह एक लाइब्रेरी भी प्रदान करता है जिसमें एक जावास्क्रिप्ट पार्सर, लेक्सर, सुंदर प्रिंटर और एक पेड़ विज़िटर शामिल है।

डेमो:

कल्पना कीजिए हम निम्नलिखित जावास्क्रिप्ट कोड है:

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

और अब हम data वस्तु से email, phone और name मूल्यों को प्राप्त करने की आवश्यकता है।

विचार यहाँ एक slimit पार्सर का दृष्टांत के लिए, सभी नोड्स पर जाते हैं, सभी कार्य को फ़िल्टर और उन्हें शब्दकोश में डाल दिया होगा:

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 

यह प्रिंट:

{'name': "'XYZ'", 
'url': "'http://www.example.com'", 
'type': '"POST"', 
'phone': "'9999999999'", 
'data': '', 
'email': "'[email protected]'"} 
+1

यह बहुत अच्छा है! इसके अलावा आप प्रत्येक मान को एक शब्दकोश के रूप में एक्सेस कर सकते हैं, जैसे: 'प्रिंट फ़ील्ड [' url '] ' – aesede

7

मैं esprima अनुवाद किया है .js से पायथन:

https://github.com/PiotrDabkowski/pyjsparser

यह एक मैन्युअल अनुवाद है इसलिए यह बहुत तेज है, angular.js फ़ाइल (इसलिए प्रति सेकेंड 100k वर्ण) को पार्स करने में लगभग 1 सेकंड लगता है। यह पूरे ईसीएमएस्क्रिप्ट 5.1 और संस्करण 6 के हिस्सों का समर्थन करता है - उदाहरण के लिए तीर फ़ंक्शंस, const, let

वैकल्पिक रूप से आप एस्प्रिमा के नए संस्करण के automated translation का उपयोग पाइथन से कर सकते हैं जो महान काम करता है और संपूर्ण जावास्क्रिप्ट 6 का समर्थन करता है!