2012-07-25 43 views
9

Tôi có cùng một câu hỏi như PEG for Python style indentation, nhưng tôi muốn nhận thêm một chút hướng liên quan đến this answer.Cấp độ thụt lề phân tích cú pháp với PEG.js

Câu trả lời tạo thành công một chuỗi các chuỗi là mỗi dòng đầu vào có 'INDENT' và 'DEDENT' giữa các dòng. Có vẻ như anh ấy đã sử dụng khá nhiều PEG.js để mã hóa, nhưng không có phân tích cú pháp thực sự nào đang xảy ra.

Vậy làm cách nào để tôi có thể mở rộng ví dụ của mình để thực hiện phân tích cú pháp thực tế?

Như một ví dụ, làm thế nào tôi có thể thay đổi ngữ pháp này:

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 = '}' 

sử dụng thụt đầu dòng thay vì niềng răng khoanh định các khối, và vẫn nhận được đầu ra giống nhau không?

(Sử dụng http://pegjs.majda.cz/online để kiểm tra ngữ pháp mà với đầu vào sau: a{bcd{zyx{}}})

Trả lời

18

Parser:

// 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(); } 

Input:

a 
    b 
    c 
    d 
    z 
    y 
    x 

Output:

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

Nó không thể phân tích một đối tượng trống (last x), tuy nhiên, nó sẽ dễ dàng để giải quyết. Thủ thuật ở đây là quy tắc SAMEDENT, nó thành công khi mức thụt lề không thay đổi. INDENTDEDENT thay đổi mức thụt dòng hiện tại mà không thay đổi vị trí trong văn bản pos = offset.

+0

Tôi thực sự đánh giá cao điều này anwser. Làm thế nào để bạn đến với phương pháp này xin vui lòng? – jiyinyiyong

+0

Nếu tôi sao chép/dán trực tiếp vào http://pegjs.majda.cz/online thì nó sẽ không biên dịch. Và sau khi một số tinh chỉnh nó không phải là rõ ràng làm thế nào để "sửa chữa" nó. – Clearly

+0

Chỉ cần thử nghiệm này, đoạn mã biên dịch và sản xuất sản lượng dự kiến ​​tốt. Không chắc chắn bạn đã nhấn vào lỗi nào. – chakrit

Các vấn đề liên quan