Lấy biểu thức chính quy cho kiểu C / ** / bình luận


8

Tôi đang làm việc với trình phân tích cú pháp cho ngôn ngữ kiểu C và đối với trình phân tích cú pháp đó, tôi cần biểu thức chính quy khớp với kiểu C / ** / nhận xét. Bây giờ, tôi đã tìm thấy biểu thức này trên web:

/\*([^\*]*\*+[^\*/])*([^\*]*\*+|[^\*]*\*/

Tuy nhiên, như bạn có thể thấy, đây là một biểu hiện khá lộn xộn và tôi không biết liệu nó có thực sự khớp với chính xác những gì tôi muốn nó phù hợp hay không.

Có một cách khác (nghiêm ngặt) xác định các biểu thức chính quy dễ kiểm tra bằng tay rằng chúng có thực sự chính xác không, và sau đó có thể chuyển đổi ('có thể biên dịch') thành biểu thức chính quy ở trên không?


2
Lưu ý rằng phương pháp này sẽ ngăn chặn các bình luận lồng nhau. Nếu bạn đang xây dựng một trình phân tích cú pháp đầy đủ, bạn có thể muốn xem xét phân tích cú pháp bình luận khối "đúng cách". không chỉ bị ràng buộc rõ ràng hơn, bạn còn có thể đọc dữ liệu meta có cấu trúc từ các bình luận nếu bạn muốn.
Raphael

Là những mảnh vỡ (!\*)dự định? Bạn có nghĩa là ký hiệu phổ biến hơn [^*]? Và những gì (!*|!/)?
Gilles 'SO- ngừng trở thành ác quỷ'

@Gilles: Tôi đã cập nhật biểu thức. (! * |! /) được dự định là một cái gì đó không phải là * hoặc /.
Alex ten Brink

@Raphael, trong C bình luận không làm tổ .
vonbrand

@vonbrand: "Phong cách C" không cụ thể lắm, vì vậy việc đề cập đến việc "tăng cường tự nhiên" là không thể là một điểm hợp lệ.
frafl 20/03/13

Câu trả lời:


6

Tôi có thể nghĩ về bốn cách:

  1. Xác định một máy tự động cho ngôn ngữ mà bạn quan tâm. Chuyển đổi biểu thức chính quy thành máy tự động (sử dụng các dẫn xuất của Brzozowski). Kiểm tra xem cả hai automata có chấp nhận cùng một ngôn ngữ (xác định và giảm thiểu hoặc sử dụng đối số chia nhỏ).

  2. Viết vô số trường hợp kiểm tra và áp dụng biểu thức chính quy của bạn cho chúng.

  3. Chuyển đổi tự động được xác định trong điểm 1 thành biểu thức chính quy, sử dụng các kỹ thuật tiêu chuẩn.

  4. Một sự kết hợp của ở trên.


5

Nếu bạn muốn chắc chắn rằng bạn đang phân tích các bình luận C, bạn cần phải đối đầu với mô hình của mình với đặc tả C. C99 §6.4.9 định nghĩa cú pháp của các bình luận như sau:

1. Ngoại trừ trong một hằng ký tự, một chuỗi ký tự hoặc một nhận xét, các ký tự /* giới thiệu một nhận xét. Nội dung của một nhận xét như vậy chỉ được kiểm tra để xác định các ký tự đa nhân và để tìm các ký tự */kết thúc nó.

2. Ngoại trừ trong một hằng ký tự, một chuỗi ký tự hoặc một nhận xét, các ký tự //giới thiệu một nhận xét bao gồm tất cả các ký tự đa dòng cho đến, nhưng không bao gồm, ký tự dòng mới tiếp theo. Nội dung của một nhận xét như vậy chỉ được kiểm tra để xác định các ký tự đa dòng và để tìm ký tự dòng mới kết thúc.

Đây là văn xuôi tiếng Anh, không phải là một định nghĩa chính thức, nhưng có một cách giải thích hợp lý rõ ràng về mặt tự động hữu hạn không xác định (NFA) tiêu thụ một nhận xét:

  • Từ trạng thái ban đầu, /tiếp theo là* vào trạng thái bình luận đa dòng và /tiếp theo là /vào trạng thái bình luận đơn dòng.
  • Từ trạng thái bình luận đa dòng, * tiếp theo là/ vào trạng thái bình luận.
  • Từ trạng thái bình luận trong một dòng, một dòng mới đi vào trạng thái bình luận.
  • Bất kỳ nhân vật khác để lại trạng thái không thay đổi.

Lưu ý rằng để biết liệu trạng thái ban đầu có áp dụng hay không, bạn phải thực hiện phân tích thêm một chút để phát hiện chuỗi ký tự và ký tự.

Khi bạn có NFA, bạn có thể sử dụng các kỹ thuật tiêu chuẩn để xây dựng biểu thức chính quy (tôi không thấy chúng trong các bài viết trên Wikipedia, nhưng chúng nên được thảo luận trong sách giáo khoa).

Nếu bạn đã có một biểu thức chính quy và muốn kiểm tra nó, bạn có thể so sánh ngôn ngữ được tạo với ngôn ngữ được tạo từ NFA được suy ra từ đặc tả ngôn ngữ: sự bình đẳng của các ngôn ngữ thông thường là có thể quyết định. Một cách để quyết định sự bình đẳng là xây dựng một máy tự động xác định tối thiểu cho mỗi loại; nếu các ngôn ngữ là tương đương, các DFA tối thiểu sẽ là đẳng cấu.


Một tìm kiếm trên Google Books cho thông tin này cho Kleene của thuật toán: books.google.co.uk/...
rgrig

0

Nếu bạn đang viết một trình phân tích cú pháp, loại công cụ này được xử lý bởi bộ phân tích từ vựng. Và ở đó bạn có thể diễn đạt điều này bằng các biểu thức thông thường, hoặc (như các flexví dụ tôi đã thấy) chỉ "thoát ra khỏi ngôn ngữ cơ bản" và hoàn thành công việc ở đó. Tức là, khi nhìn thấy /*chỉ cần bỏ qua phía trước cho đến khi bạn tìm thấy */(một DFA cho việc này dễ xây dựng, và từ đó một đoạn C rất đơn giản để viết).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.