2011-08-24 29 views
5

Cố gắng tìm hiểu tinh thần tăng cường và ví dụ được đưa ra trong tài liệu khiến tôi hơi bối rối.Tăng tinh thần Số phân tích cú pháp số La Mã Ví dụ

Đề cập đến mã này:

http://www.boost.org/doc/libs/1_46_1/libs/spirit/example/qi/roman.cpp

Riêng phân khúc này của ngữ pháp:

 start = eps    [_val = 0] >> 
      (
       +lit('M')  [_val += 1000] 
       || hundreds [_val += _1] 
       || tens  [_val += _1] 
       || ones  [_val += _1] 
      ) 

Có thể ai đó giải thích cho tôi lý do tại sao nó được + thắp sáng ('M') và không * thắp sáng ('M'). Bởi vì sau khi tất cả không thể có không hoặc nhiều M so với một hoặc nhiều M?

Trả lời

0

Cả hai +lit('M')*lit('M') đều chính xác. Nhưng trước đây là dễ đọc hơn sau này (theo ngữ nghĩa), theo ý kiến ​​của tôi, như trước đây nói thêm1000 đến _val nếu có one khớp và lặp lại nhiều lần. Mặt khác, cái sau rất khó đọc, vì người ta có thể đọc nó như là thêm1000 đến _val ngay cả đối với kết quả không khớp là sai. 1000 không được thêm vào _val cho đối sánh 0 lần, nhưng trình phân tích cú pháp *lit('M') dường như phù hợp với không khớp cũng (có vẻ khó hiểu).

Vì vậy, +lit('M') là thích hợp hơn.


Được rồi. Tôi đọc bình luận của bạn. CCLLIX không phải là số La Mã hợp lệ. Bạn nghĩ giá trị của nó là gì? 309? Nếu vậy, thì giá trị nào sẽ là CCCIX? Nó quá 309, và chính xác. Của bạn là sai. Do đó trình phân tích cú pháp dừng lại khi bạn sử dụng *lit('M'). Cũng lưu ý rằng trình phân tích cú pháp cũng sẽ dừng ngay cả khi bạn sử dụng +lit('M') cho đầu vào sai này.

+0

Sử dụng * lit ('M') và CCLLIX. Vậy tại sao kết quả trả về 250 và dừng tại LIX? Như bạn đã nói, không nên thêm 1000 vào _val cho 0 trận đấu và CCLLIX không có M. Vậy có nên trả lại 1250 không 250? – Integer

+1

@Integer: Tôi đã thêm phần giải thích. 'CCLLIX' KHÔNG phải là số hợp lệ. – Nawaz

+0

Bắt tốt. Xin lỗi vì điều đó. Nhưng ngay cả khi tôi sử dụng CCLIX cả hai sử dụng * và + kết quả trong câu trả lời đúng của 259.Tại sao không * kết quả trong 1259 như bạn nói? – Integer

2

Các a || b nhà điều hành trong Thần Khí có nghĩa a hoặc b, nhưng b sau a, nếu a xảy ra. Trong sự sắp xếp của toán tử, trường hợp không có M là ẩn (vì kết quả phù hợp cho M có thể có hoặc không có mặt). Ngoài ra, trong trường hợp của *lit('M'), bạn có nói rằng quy tắc đầu tiên được đối sánh nếu có NOM? Tuy nhiên, nó sẽ hợp lệ và _val sẽ được tăng thêm 1000.

+0

Nhưng _val không tăng lên khi không có M. Tôi đã thử sử dụng CCLIX đầu vào và nó trả lại giá trị đúng 259 nếu tôi sử dụng + hoặc * – Integer

+0

Vâng, rằng * có thể * phụ thuộc vào việc triển khai thực hiện. Các ngữ nghĩa rõ ràng theo nghĩa quy tắc * có thể * được so khớp (vì vậy nó có thể thực thi mã), vì vậy tốt hơn nên sử dụng '+', bởi vì 0 khớp được ngụ ý bởi toán tử '||'. –

0

Đó là (Một hoặc nhiều Ms) HOẶC hàng trăm HOẶC hàng chục HOẶC hàng. (Zero trở lên Ms) HOẶC hàng trăm hoặc hàng chục HOẶC người sẽ phù hợp với không Bà còn gọi là chuỗi rỗng và vô nghĩa thêm 1000.

+0

Điều này không đúng. Tôi đã thử truyền một chuỗi rỗng và không thêm 1000 khi sử dụng giải pháp sao Kleene * được chiếu sáng ('M') – Integer

0

Phù hợp với biểu hiện A || B trong Qi có nghĩa là phù hợp với chỉ A, hoặc chỉ B hoặc A followed by B. Do đó, trong trường hợp của bạn +lit('M') || hundreds có nghĩa là +lit('M') hoặc hundreds hoặc +lit('M')followed by hundreds. Vì lý do này ngữ pháp cho phép khớp với bất kỳ số La Mã nào thậm chí không bắt đầu bằng một số M.

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