Tại sao tính linh hoạt của Forth làm cho một ngữ pháp không phù hợp với nó?


10

Gần đây tôi đã thực hiện nhiệm vụ viết một ngôn ngữ lập trình dựa trên ngăn xếp. Trước khi tôi bắt đầu thiết kế ngôn ngữ của mình, tôi nghĩ rằng nên đọc và thử nghiệm với các ngôn ngữ dựa trên ngăn xếp hiện có.

Điều này đưa tôi đến chủ đề của bài viết này. Tôi đã đọc qua bài viết trên Wikipedia về Forth , một ngôn ngữ dựa trên ngăn xếp sử dụng các biểu thức kiểu hậu tố. Trong bài viết, tôi đã thấy tuyên bố sau:

Tính linh hoạt của Forth làm cho ngữ pháp BNF tĩnh không phù hợp và nó không có trình biên dịch nguyên khối. Mở rộng trình biên dịch chỉ yêu cầu viết một từ mới, thay vì sửa đổi ngữ pháp và thay đổi cách thực hiện cơ bản.

Theo hiểu biết của tôi, trong biệt ngữ Forth, thuật ngữ "từ" dường như về cơ bản đồng nghĩa với "chương trình con". Với điều này, tuyên bố trên có vẻ lạ. Tại sao chính xác khả năng tạo các chức năng mới trong Forth sẽ tạo ra một ngữ pháp chính thức cho Forth không phù hợp? Tại sao bạn cần phải viết lại ngữ pháp cho mỗi chương trình con mới mà bạn xác định? Làm thế nào để viết một từ mới trong môi trường tạo thành mở rộng trình biên dịch? Tuyên bố trên có vẻ giống như nói rằng một ngữ pháp chính thức không phù hợp với Python vì bạn có thể xác định các hàm mới.

Trên thực tế, tôi đã quyết định thử viết một ngữ pháp kiểu BNF cho một tập hợp con đơn giản của Forth bên dưới:

program        ::= stmt+
stmt           ::= func | expr
func           ::= ':' expr+ ';'
expr           ::= INTEGER | word
word           ::= ('+' | '-' | '*' | '/' )

Ngữ pháp trên dường như bao trùm một tập hợp con các câu lệnh Forth hợp lệ và dường như không khó để mở rộng để bao quát tất cả các câu lệnh hợp lệ trong ngôn ngữ Forth. Hơn nữa, nếu trình phân tích cú pháp của trình biên dịch thực hiện ngữ pháp trên, tôi không thấy trình biên dịch sẽ được mở rộng như thế nào. Trình biên dịch sẽ chỉ cần thêm bất kỳ từ mới nào vào môi trường của nó . Chỉ có môi trường được thay đổi. Có vẻ như đoạn trích trên từ Wikipedia đang kết hợp mã gạch chân cấu thành trình biên dịch (không thay đổi) với môi trường của trình biên dịch (không thay đổi).

Tóm lại, tại sao ablitiy của Forth định nghĩa các từ mới (chương trình con) làm cho không phù hợp với ngữ pháp viết?


1
"Không phù hợp" là một từ mạnh mẽ trong bối cảnh này. Một từ tốt hơn có lẽ sẽ là "không cần thiết."
Robert Harvey

1
Ồ, được thôi @RobertHarvery. Tuy nhiên, nếu đó là trường hợp, thì đoạn trích tôi trích dẫn dường như sẽ áp dụng cho hầu hết các ngôn ngữ. Về mặt kỹ thuật không bao giờ cần một ngữ pháp , nhưng thật tuyệt khi có một ngữ pháp - đặc biệt là khi các trình phân tích cú pháp viết tay.
Christian Dean

Nhưng trong hầu hết các ngôn ngữ, trình phân tích cú pháp không phải là một thư viện thời gian chạy đơn giản có thể được thay đổi bởi mã người dùng, do đó ảnh hưởng đến cách dòng tiếp theo được phân tích cú pháp.
Jörg W Mittag

Câu trả lời:


10

Một từ "bình thường" gần như chỉ là một chương trình con.

... nhưng bạn có thể viết một từ xác định do người dùng định nghĩa , nó thay đổi cách trình biên dịch hoạt động. Ví dụ: một định nghĩa thường bắt đầu bằng dấu hai chấm (":") và kết thúc bằng dấu chấm phẩy (";"). Nhưng nếu bạn muốn, bạn có thể (ví dụ) thay đổi những gì dấu hai chấm làm và trong quá trình thay đổi cách định nghĩa từ được "biên dịch", từ đó thay đổi cách trình biên dịch hoạt động và thay đổi ngữ pháp của ngôn ngữ được nhận dạng.

Đây là lý do tại sao nó nói một ngữ pháp là không phù hợp - ngữ pháp hoàn toàn có thể thay đổi từ một phần của chương trình sang một phần khác. Tải một từ điển có thể thay đổi không chỉ các chương trình con có tên hiện được công nhận, mà cả ngữ pháp được phân tích cú pháp khi bạn xác định một từ mới.


2
Bạn có chắc tài sản này của Forth thực sự thay đổi ngữ pháp và không chỉ là ngữ nghĩa?
Doc Brown

@DocBrown: Hầu hết những người sử dụng Forth thích nó khá nhiều, vì vậy họ thường chỉ thực hiện những thay đổi tối thiểu cần thiết cho nhiệm vụ trong tay. Ai đó đủ tham vọng (và điên rồ) có thể thay đổi hoàn toàn cú pháp nếu họ muốn - như sử dụng ký hiệu infix thay vì postfix, nếu họ muốn đủ tệ.
Jerry Coffin

@DocBrown Loại ngữ pháp nào bạn có thể viết có thể cho phép tôi viết trình thông dịch C trong Forth, và sau đó đột nhiên chuyển sang C ở giữa chương trình?
user253751

@immibis: tốt, câu hỏi của tôi là - Forth có thực sự cho phép một cái gì đó như thế này không? Từ bài viết được liên kết đó, điều này vốn không rõ ràng với tôi.
Doc Brown

@DocBrown Có. Bạn có thể chạy mã của mình tại thời gian biên dịch, điều đó có nghĩa là nếu bạn muốn, bạn hoàn toàn có thể tiếp quản trình biên dịch. Về cơ bản, bạn có thể chạy trình biên dịch / trình thông dịch C của mình ở giữa trình biên dịch / trình thông dịch Forth. (cuối cùng bạn có muốn quay lại Forth hay không là tùy thuộc vào bạn)
user253751

3

Trong Forth, bạn có thể chạy mã tại thời gian biên dịch.

Cụ thể, bạn có thể chạy mã tiêu thụ từ từ đầu vào. Ví dụ: bạn có thể viết trình biên dịch C trong Forth, sau đó gọi nó vào thời gian biên dịch, sau đó viết phần còn lại của chương trình vào C.

Thông thường hơn, bạn có thể định nghĩa các từ đọc đối số từ mã nguồn. Theo truyền thống, bạn sẽ đọc các từ giống như trình biên dịch, nhưng không bắt buộc.

Chẳng hạn, ."từ (in một chuỗi) không đọc cho đến không gian tiếp theo, nó đọc cho đến tiếp theo ". Nếu bạn cố phân tích mã : PRINTHELLO ." Hello ; : func2 world!" ;mà không có trường hợp đặc biệt nào .", bạn sẽ thấy rằng nó không được phân tích cú pháp chính xác.

Bạn chắc chắn có thể thêm một trường hợp đặc biệt cho ."ngữ pháp của mình, nhưng ngữ pháp sẽ vẫn không chính xác nếu lập trình viên định nghĩa từ riêng của họ như ."- ví dụ như đây là một : : MY_PRINT POSTPONE ." ; IMMEDIATE. Từ này tương đương với ."; Tôi có thể viết MY_PRINT Hello ; world! "và ngữ pháp của bạn cần để có thể phân tích cú pháp. Chúc may mắn với điều đó.

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.