2015-03-09 37 views
6

Ngôn ngữ lệnh shell POSIX không dễ phân tích cú pháp, chủ yếu là do khớp nối chặt chẽ giữa lexing và phân tích cú pháp.Phân tích cú pháp ngữ pháp biểu thức có phù hợp để phân tích cú pháp ngôn ngữ lệnh shell không?

Tuy nhiên, phân tích cú pháp ngữ pháp biểu thức (PEG) thường không cần quét. Bằng cách kết hợp lexing và phân tích cú pháp, có vẻ như tôi có thể tránh được những vấn đề này. Ngôn ngữ tôi đang sử dụng (Rust) có một thư viện PEG được duy trì tốt. Tuy nhiên, tôi biết ba khó khăn có thể khiến việc sử dụng thư viện này không thực tế:

  • Vỏ phải có khả năng phân tích từng dòng, không đọc ký tự ở cuối dòng.
  • biệt hiệu là hoàn toàn từ vựng, và có thể gây ra một mã thông báo để được thay thế bằng bất kỳ chuỗi các thẻ khác trong một số tình huống
  • Shell từ dành riêng chỉ được ghi nhận trong một số tình huống

là một PEG phù hợp với phân tích cú pháp ngôn ngữ lệnh shell cho các yêu cầu này, hoặc là một trình phân tích cú pháp đệ quy-viết tay thích hợp hơn?

+0

FWIW, bash sử dụng trình phân tích cú pháp được tạo bằng bison khá đơn giản, được kết hợp với một từ viết tay cực kỳ phức tạp. Tôi không biết PEG sẽ hoạt động tốt như thế nào, nhưng nếu bạn thử, hãy cho chúng tôi biết. – rici

+5

Ba lý do: đó là GPL trong khi trình bao của tôi thuộc MIT/Apache 2, nó nằm trong C trong khi shell của tôi nằm trong Rust, và tôi sẽ không học được gì từ nó. – Demi

+0

Có. Trình phân tích cú pháp PEG thực hiện quét. Ngôn ngữ ngữ pháp mạnh hơn các biểu thức thông thường và nhỏ gọn và tiện lợi. Tôi đã dịch vài ngữ pháp ANTLR sang Grako (PEG), và phần từ vựng đã dịch dễ dàng. Tuy nhiên, PEG sẽ kém hiệu quả hơn so với lexer dựa trên máy trạng thái. – Apalala

Trả lời

3

Có, PEG có thể được sử dụng và không có vấn đề nào bạn lưu ý là một vấn đề. Cụ thể:

1) phân tích cú pháp từng dòng: hầu hết các công cụ PEG sẽ không có bất kỳ dấu cách trắng nào được tích hợp sẵn. Tất cả không gian màu trắng bao gồm cả dòng mới phải được xử lý một cách rõ ràng bởi bạn, có nghĩa là bạn có thể xử lý dòng mới theo bất kỳ cách nào bạn muốn.

2) Bạn không nên sử dụng cây phân tích cú pháp từ PEG làm AST của bạn. Thay vào đó bạn nên hạ xuống cây phân tích và xây dựng một AST. Đối với các bí danh, sau khi phân tích cú pháp đã hoàn thành và bạn đang xây dựng AST của mình, bạn có thể phát hiện bí danh và chèn mở rộng thích hợp cho bí danh thay thế.

3) Các từ dành riêng không được đặt trước trừ khi bạn đặt trước. Tức là, nếu bạn có một ngữ cảnh hoặc một từ riêng hoặc một ký tự chữ số khác có thể xuất hiện, trước tiên bạn phải kiểm tra các từ dành riêng, sau đó là ký hiệu chữ và số tùy ý, bởi vì một khi PEG quyết định nó có khớp, nó sẽ không quay lại -track. Bất cứ nơi nào một từ dành riêng không được phép, chỉ đơn giản là không kiểm tra nó, và quy tắc biểu tượng chữ và số tổng quát của bạn sẽ thành công thay thế.

+0

Tôi hơi lạc hậu, nhưng tôi đọc từ "bí danh" là "macro không tham số". Ai nói rằng việc mở rộng macro phải tạo thành một cụm từ trong ngữ pháp mà bạn cung cấp? Nếu không, bạn không thể chỉ là "thay thế cây". (Thành thật mà nói, chúng được dễ dàng xử lý bằng cách đơn giản mở rộng chúng khi lexer gặp chúng). –

+0

@Ira: Bí danh vỏ truyền thống về cơ bản là thay thế văn bản - mọi văn bản sau đây trên lời gọi được phân tích cú pháp như là một phần của việc mở rộng. Vì vậy, trong khi những gì bạn nói có thể đúng với bí danh trong các ngôn ngữ khác hoặc trong các trình bao cao cấp hơn thì thay thế văn bản sẽ hầu như luôn chính xác. Hơn nữa: AST không phải là một cây phân tích, như tôi đã nói.Bạn làm bất cứ điều gì thay thế tạo ra các ngữ nghĩa bí danh đúng. – cliffordheath

+0

"Hầu như luôn luôn?" cho chuỗi "if (pqr abc" với pqr là bí danh của "a> b)", làm cách nào bạn có thể phân tích cú pháp chuỗi và sau đó thay thế bí danh sau? –

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