2012-02-07 32 views
5

Tôi sẽ thực hiện các hướng dẫn Tăng cường tinh thần (và Boost Fusion) (phiên bản 1.48.0). Tôi đã chơi với ví dụ nhân viên đồ chơi. Các liên kết đến nguồn là ở đây:Boost :: Ví dụ ngữ pháp tinh thần đơn giản

http://www.boost.org/doc/libs/1_48_0/libs/spirit/example/qi/employee.cpp

Đây là của ví dụ ngữ pháp:

employee_parser() : employee_parser::base_type(start) 
    { 
     using qi::int_; 
     using qi::lit; 
     using qi::double_; 
     using qi::lexeme; 
     using ascii::char_; 

     quoted_string %= lexeme['"' >> +(char_ - '"') >> '"']; 

     start %= 
      lit("employee") 
      >> '{' 
      >> int_ >> ',' 
      >> quoted_string >> ',' 
      >> quoted_string >> ',' 
      >> double_ 
      >> '}' 
      ; 
    } 

    qi::rule<Iterator, std::string(), ascii::space_type> quoted_string; 
    qi::rule<Iterator, employee(), ascii::space_type> start; 

Và thay đổi tôi loại bỏ việc điều trị các dấu ngoặc kép và chỉ phân tích bất kỳ ký tự giữa delimiter và gán với cấu trúc mà trình phân tích cú pháp được ánh xạ tới.

 //quoted_string %= lexeme['"' >> +(char_ - '"') >> '"']; 
     start %= 
      lit("employee") 
      >> '{' 
      >> int_ >> ',' 
      >> +(char_) >> ',' 
      >> +(char_) >> ',' 
      >> double_ 
      >> '}' 
      ; 

Giả định của tôi là char_ bao gồm tất cả các ký tự cho đến khi đạt đến dấu phẩy. Tuy nhiên, việc biên dịch và chạy với chuỗi sau sẽ trả về lỗi không phân tích cú pháp.

./employee 
employee{10,my,name,20.0} 
------------------------- 
Parsing failed 
------------------------- 

Tôi cũng đang cố viết một trình phân tích cú pháp tương tự để tự động truyền tới các loại cấu trúc thích hợp của tôi. Tôi chắc rằng tôi đang thiếu một cái gì đó về cơ bản sai như xa như việc xác định ngữ pháp chính xác cho một chuỗi đầu vào như trên, vì vậy bất kỳ trợ giúp được đánh giá rất nhiều!

Cảm ơn!

Trả lời

10

+(char_) tiêu thụ một hoặc nhiều char, vì vậy nó cũng sẽ tiêu thụ dấu phẩy và sẽ không bao giờ di chuyển đến >> ','. Đó là tham lam.

Bạn nên viết +(char_ - ','), sử dụng sự khác biệt điều hành -:

//... 
>> int_ >> ','  
>> +(char_ - ',') >> ','  
>> +(char_ - ',') >> ','  
>> double_ 
//... 

Parser +(char_ - ',') sẽ tiêu thụ mỗi char cho đến khi dấu phẩy là đạt. Sau đó nó sẽ di chuyển đến >> ',', tiêu thụ nó và sau đó tiếp tục với dòng tiếp theo +(char_ - ',') cho đến khi dấu phẩy và vân vân.

Thông tin thêm về điều hành này, bạn có thể tìm thấy ở đây: http://www.boost.org/doc/libs/1_48_0/libs/spirit/doc/html/spirit/qi/reference/operator/difference.html

HOẶC

Nếu bạn muốn phân tích cái tên mà chỉ chứa chữ cái, bạn cũng có thể xem xét viết phân tích cú pháp mà chỉ chấp nhận chữ:

//... 
>> int_ >> ','  
>> +(char_("a-zA-Z")) >> ','  
>> +(char_("a-zA-Z")) >> ','  
>> double_ 
//... 
+2

... chỉ là chữ cái ASCII, sau đó ... José không thích thú. ;-) – DevSolar

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