PEG.js

2012-07-25 9 views
9

के साथ पार्स इंडेंटेशन स्तर मेरे पास अनिवार्य रूप से PEG for Python style indentation जैसा प्रश्न है, लेकिन मैं this answer के बारे में थोड़ा और दिशा प्राप्त करना चाहता हूं।PEG.js

उत्तर सफलतापूर्वक स्ट्रिंग्स की एक सरणी उत्पन्न करता है जो लाइनों के बीच 'इंडेंट' और 'डेडेंट' के साथ इनपुट की प्रत्येक पंक्ति होती है। ऐसा लगता है कि वह टोकननाइज़ करने के लिए बहुत अधिक उपयोग किए गए PEG.js है, लेकिन कोई असली पार्सिंग नहीं हो रहा है।

तो मैं कुछ वास्तविक पार्सिंग करने के लिए अपना उदाहरण कैसे बढ़ा सकता हूं?

start = obj 
obj = id:id children:(indent obj* outdent)? 
     { 
      var o = {}; 
      o[id] = children[1]; 
      return (children[1] ? o : id); 
     } 
id = [a-z] 
indent = '{' 
outdent = '}' 

ब्रेसिज़ के बजाय खरोज उपयोग करने के लिए ब्लॉक चित्रित करने के लिए, और अभी भी एक ही आउटपुट मिलता है:

एक उदाहरण के रूप में, मैं इस व्याकरण कैसे बदल सकते हैं?

(निम्नलिखित इनपुट के साथ कि व्याकरण का परीक्षण करने के http://pegjs.majda.cz/online का उपयोग करें: a{bcd{zyx{}}})

उत्तर

18

पार्सर:

// do not use result cache, nor line and column tracking 

{ var indentStack = [], indent = ""; } 

start 
    = INDENT? l:line 
    { return l; } 

line 
    = SAMEDENT line:(!EOL c:. { return c; })+ EOL? 
    children:(INDENT c:line* DEDENT { return c; })? 
    { var o = {}; o[line] = children; return children ? o : line.join(""); } 

EOL 
    = "\r\n"/"\n"/"\r" 

SAMEDENT 
    = i:[ \t]* &{ return i.join("") === indent; } 

INDENT 
    = &(i:[ \t]+ &{ return i.length > indent.length; } 
     { indentStack.push(indent); indent = i.join(""); pos = offset; }) 

DEDENT 
    = { indent = indentStack.pop(); } 

इनपुट:

a 
    b 
    c 
    d 
    z 
    y 
    x 

आउटपुट:

{ 
    "a": [ 
     "b", 
     "c", 
     { 
     "d": [ 
      "z", 
      "y", 
      "x" 
     ] 
     } 
    ] 
} 

यह एक खाली वस्तु (अंतिम x) को पार्स नहीं कर सकता है, हालांकि, इसे हल करना आसान होना चाहिए। यहां ट्रिक SAMEDENT नियम है, यह तब बढ़ता है जब इंडेंटेशन स्तर नहीं बदला जाता है। INDENT और DEDENT टेक्स्ट pos = offset में स्थिति बदलने के बिना वर्तमान इंडेंटेशन स्तर बदलें।

+0

मैं वास्तव में इस anwser की सराहना करता हूं। आप इस विधि के साथ कैसे आते हैं? – jiyinyiyong

+0

यदि मैं इसे सीधे http://pegjs.majda.cz/online में कॉपी/पेस्ट करता हूं तो यह संकलित नहीं होता है। और कुछ tweaking के बाद यह स्पष्ट नहीं है कि इसे कैसे "ठीक करें"। – Clearly

+0

बस इसका परीक्षण किया गया, स्निपेट संकलित और अपेक्षाकृत आउटपुट का उत्पादन ठीक है। सुनिश्चित नहीं है कि आपने वहां कौन सी त्रुटियां डालीं। – chakrit