2012-05-16 25 views
8

Bạn muốn khai báo biến nào trong trường hợp đó, phạm vi toàn cầu hoặc khai báo @members? Dường như với tôi rằng họ có thể phục vụ cho cùng một mục đích?tuyên bố phạm vi quy tắc chống lừa đảo toàn cầu và khai báo @members

CẬP NHẬT đây là ngữ pháp để giải thích ý tôi.

grammar GlobalVsScope; 

scope global{ 
    int i; 
} 
@lexer::header{package org.inanme.antlr;} 
@parser::header{package org.inanme.antlr;} 

@parser::members { 
    int j; 
} 

start 
scope global; 
@init{ 
    System.out.println($global::i); 
    System.out.println(j); 
}:R EOF; 

R:'which one'; 
+0

hãy xem xét ngữ pháp mẫu. –

+0

Ah, không phải là * phạm vi * của ngôn ngữ đích, nhưng phạm vi ANTLR * *. Tôi hiểu. –

Trả lời

9

Lưu ý rằng bên cạnh toàn cầu (ANTLR) phạm vi, bạn cũng có thể địa phương quy tắc phạm vi, như thế này:

grammar T; 

options { backtrack=true; } 

parse 
scope { String x; } 
parse 
: 'foo'? ID {$parse::x = "xyz";} rule* 
| 'foo' ID 
; 

rule 
: ID {System.out.println("x=" + $parse::x);} 
; 

Thời gian duy nhất tôi muốn xem xét sử dụng địa phương rule- phạm vi là khi có nhiều biến vị ngữ hoặc tính năng backtracking toàn cầu được bật (dẫn đến tất cả các quy tắc có các biến vị ngữ trước chúng). Trong trường hợp đó, bạn có thể tạo biến thành viên String x (hoặc xác định nó trong phạm vi toàn cầu) và đặt nó trong quy tắc parse, nhưng bạn có thể thay đổi biến thể/phạm vi này sau đó trình phân tích cú pháp có thể quay lại và sẽ không khiến biến toàn cục được đặt thành dạng/trạng thái ban đầu của nó! Biến phạm vi cục bộ cũng sẽ không phải là là "không được đặt", nhưng điều đó có thể sẽ ít rủi ro hơn: chúng là cục bộ cho một quy tắc duy nhất.

Để tóm tắt: có, bạn nói đúng, phạm vi toàn cầu và biến thành viên/ví dụ giống nhau. Nhưng tôi sẽ sớm chọn tham gia biến thành viên vì cú pháp thân thiện hơn.

+0

vẫn đang tiêu hóa, cảm ơn rất nhiều! –

+0

@mertinan, xin lỗi, câu trả lời trước đó của tôi không hoàn toàn đúng (và một chút mơ hồ, có lẽ). Xem phiên bản đã chỉnh sửa của tôi. –

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