Có phải ngôn ngữ của Biểu thức chính quy cần một automata đẩy xuống để phân tích nó?


12

Tôi muốn chuyển đổi một người dùng đã nhập biểu thức chính quy thành NFA để sau đó tôi có thể chạy NFA theo chuỗi cho các mục đích phù hợp. Máy tối thiểu có thể được sử dụng để phân tích các biểu thức thông thường là gì?

Tôi cho rằng nó phải là một máy tự động đẩy xuống bởi vì giá trị của dấu ngoặc có nghĩa là cần phải đếm và DFA / NFA không thể thực hiện đếm tùy ý. Giả định này có đúng không? Ví dụ: biểu thức a (bc *) d sẽ yêu cầu một thiết bị PDA để biểu thức phụ trong ngoặc được xử lý chính xác.


1
Bạn có ý nghĩa chính xác bằng cách "phân tích cú pháp"? Bạn có nghĩa là kiểm tra xem đầu vào có thực sự là một biểu thức chính quy hay bạn có một điều phức tạp hơn trong đầu, ví dụ như một máy xuất ra một mô tả về NFA tương ứng? (nếu bạn không chắc chắn liệu đầu vào có thực sự là một biểu thức chính quy hay không và bạn cần kiểm tra nó thì bạn cần phải kiểm tra dấu ngoặc đơn có đúng không và điều đó thường có nghĩa là sử dụng ngăn xếp.)
Kaveh

Đối với một câu trả lời thực tế, bạn có thể nhìn vào Plan 9 nguồn Grep cho grep.y .
Bruce Ediger

Câu trả lời:


8

Bạn nói đúng. Thật dễ dàng để chỉ ra rằng cú pháp của biểu thức chính quy không thường xuyên bằng cách sử dụng các kỹ thuật tiêu chuẩn .

REG(p)p

Điều đó nói rằng, có lẽ bạn không muốn mã hóa một chiếc PDA bằng tay. Cân nhắc sử dụng trình tạo phân tích cú pháp như ANTLR hoặc byacc . Mặt khác, nếu bạn muốn điều tra phân tích cú pháp các ngôn ngữ bằng cách lập trình các trình phân tích cú pháp, bạn nên tiếp tục với các thuật toán phân tích cơ bản khác như CYK , Earley , gốc đệ quyLR .


cảm ơn. viết mã cho các nhiệm vụ này tạo ra sự hiểu biết tốt hơn và không nhằm mục đích hiệu quả như các tiện ích hiện có như lex, yacc, bison, v.v.
Phil Wright

@PhilWright: Tôi thấy, tốt đẹp! Tôi chỉnh sửa trong con trỏ thêm cho trường hợp này.
Raphael

Tôi thích một trình phân tích cú pháp gốc đệ quy được mã hóa bằng tay cho cái này.
Dave Clarke

Nếu viết một trình phân tích cú pháp bằng tay cho việc này, thì việc đệ quy đệ quy (sau bao thanh toán và tạo khối) là một tùy chọn, trình phân tích cú pháp LCC cho C < site.google.com/site/lccretargetablecompiler > có một cách thú vị để xử lý nhiều toán tử. Nhưng có lẽ dễ nhất để xây dựng bằng tay là phân tích cú pháp ưu tiên.
vonbrand

3

Tôi đề nghị bạn đọc câu trả lời hay của Jukka cho câu hỏi " Ghép các biểu thức chính quy bằng các biểu thức chính quy " trên cstheory, quá. Một đoạn trích:

Ví dụ: chúng ta có thể sửa đổi ký hiệu chuẩn như sau để thu được các biểu thức chính quy "nén" :

  • Bạn được phép xóa bất kỳ tiền tố nào bao gồm một chuỗi ('s
  • Bạn được phép xóa bất kỳ hậu tố nào bao gồm một chuỗi)

Đó là, ((a|b)*c)de(f|g)có thể được thể hiện bằng các ký hiệu "nén" sử dụng, ví dụ, một trong các hình thức sau: a|b)*c)de(f|ghoặc ((a|b)*c)de(f|ghoặc (a|b)*c)de(f|g).

[...]

Ký hiệu "nén" (của biểu thức chính quy) là ngôn ngữ thông thường.

Đây chỉ là một liên kết đến một "quan điểm khác biệt" thú vị (theo tôi) về ngôn ngữ biểu thức chính quy; như được gạch chân trong các ý kiến ​​dưới đây, nó không hữu ích để xây dựng cây cú pháp. Nếu bạn muốn viết mã trình phân tích cú pháp của mình, tôi sẽ gợi ý cho bạn bài viết đơn giản này về mật mã " Writing-own-normal-express-Parser ".


Jukka về cơ bản loại bỏ yêu cầu rằng dấu ngoặc đơn được cân bằng. Tôi biết không có trường hợp nào thực sự được thực hiện, nhưng điều đáng lưu ý là bằng cách thay đổi ngữ nghĩa, bạn có thể "đơn giản hóa" cú pháp.
Raphael

4
Bạn (và Jukka) không phân tích cú pháp biểu thức, chỉ nhận ra chúng. Sau đó, Yup, đó là một regrec (nén).
Gilles 'SO- ngừng trở nên xấu xa'
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.