Làm thế nào tôi nên thực hiện một ứng dụng xử lý lệnh?


9

Tôi muốn tạo một ứng dụng đơn giản, bằng chứng khái niệm (REPL) lấy một số và sau đó xử lý các lệnh trên số đó.

Ví dụ: Tôi bắt đầu bằng 1. Sau đó tôi viết " add 2", nó cho tôi 3. Sau đó tôi viết " multiply 7", nó cho tôi 21. Sau đó tôi muốn biết nó có phải là số nguyên tố hay không, vì vậy tôi viết " is prime" (trên số hiện tại - 21), nó cho tôi sai. " is odd" sẽ cho tôi sự thật. Và như thế.

Bây giờ, đối với một ứng dụng đơn giản với một vài lệnh, thậm chí một lệnh đơn giản switchsẽ làm để xử lý các lệnh. Nhưng nếu tôi muốn mở rộng, tôi cần phải thực hiện chức năng như thế nào? Tôi có sử dụng mẫu lệnh không? Tôi có xây dựng trình phân tích cú pháp / trình thông dịch đơn giản cho ngôn ngữ không? Nếu tôi muốn các lệnh phức tạp hơn, như " multiply 5 until >200" thì sao? Điều gì sẽ là một cách dễ dàng để mở rộng nó (thêm các lệnh mới) mà không cần biên dịch lại?

Chỉnh sửa: để làm rõ một số điều, mục tiêu cuối cùng của tôi sẽ không phải là tạo ra một cái gì đó tương tự như WolframAlpha, mà là một bộ xử lý danh sách (số). Nhưng tôi muốn bắt đầu từ từ lúc đầu (trên các số duy nhất).

Tôi đang nghĩ một cái gì đó tương tự như cách người ta sẽ sử dụng Haskell để xử lý danh sách, nhưng là một phiên bản rất đơn giản. Tôi đang tự hỏi liệu một cái gì đó giống như mẫu lệnh (hoặc tương đương) sẽ đủ, hoặc nếu tôi phải tạo một ngôn ngữ nhỏ mới và trình phân tích cú pháp để nó đạt được mục tiêu của mình?

Edit2: Cảm ơn tất cả các câu trả lời, tất cả đều rất hữu ích với tôi, nhưng Emmad Kareem đã giúp tôi nhiều nhất, vì vậy tôi sẽ chọn nó làm câu trả lời. Cảm ơn một lần nữa!


2
Tôi không nhận được downvote. Vui lòng nêu rõ lý do của bạn để tôi có thể đưa ra câu hỏi của mình tốt hơn vào lần tới.
Nini Michaels

2
Tôi thực sự thích câu hỏi này. Nhìn về phía trước để xem những gì thiết kế mọi người đề nghị. Bạn có đặc biệt tìm kiếm thiết kế hướng đối tượng (bạn đề cập đến mẫu lệnh, đó là mẫu OO)?
Bjarke Freund-Hansen

cảm ơn bạn :) vâng, tôi thích OOP hơn, nhưng tôi sẽ không phiền nếu các phương pháp khác được đề xuất!
Nini Michaels

2
Có vẻ như việc triển khai Reverse Ba Lan , một chủ đề lập trình rất hay!
Alberto De Caro

2
Có lẽ bạn đang phạm lỗi của điều khoản sách từ loại câu hỏi nào tôi không nên hỏi ở đây? trong Câu hỏi thường gặp, tức là Nếu bạn có thể tưởng tượng toàn bộ cuốn sách trả lời câu hỏi của mình, bạn đang hỏi quá nhiều .
Đánh dấu gian hàng

Câu trả lời:


5

Điều này nghe giống như một thông dịch viên. Có vẻ như bạn lo lắng về việc triển khai nhiều hơn chức năng chi tiết (tôi chỉ đoán ở đây). Dự án này nếu mở rộng không phải là một nhiệm vụ tầm thường. Hãy chắc chắn rằng bạn nghiên cứu phạm vi rõ ràng vì điều này đòi hỏi cách tiếp cận kỹ thuật chứ không phải cách tiếp cận phát triển đặc biệt để có được một sản phẩm đáng tin cậy hơn là một sản phẩm có 1000 miếng vá đôi khi chỉ hoạt động.

Quyết định một cú pháp và sẵn sàng phân tích cú pháp và thực hiện các kiểm tra cú pháp cần thiết. Liên kết này có thể giúp bạn với điều này: Tạo trình phân tích cú pháp của riêng bạn .

Hãy xem: chủ đề này khi nó liên quan đến các khía cạnh khác nhau của công việc, cũng có những liên kết tốt có thể giúp bạn (đặc biệt là câu trả lời của RMK): Tạo trình thông dịch ngôn ngữ . Bạn có thể muốn xem một ví dụ về một dự án đẹp mắt có phần giống nhau tại: Máy tính khoa học lập trình cuối cùng . Bạn có thể tìm mã nguồn và chương trình làm việc cho trình thông dịch dòng lệnh C # tại đây Dòng lệnh-Thực hiện-C--Made-for-Giảng dạy . Sử dụng trình biên dịch để thực hiện các tác vụ phức tạp cho bạn như phân tích cú pháp và gõ biến, v.v. có thể là một cách thông minh để thoát khỏi sự phức tạp của việc tự viết tất cả những điều này. Ngoài ra, có tùy chọn Mono cung cấp tính năng shell charp mà bạn có thể muốn xem qua: CsharpRepl .


Cảm ơn, các liên kết của bạn thực sự hữu ích! Vì vậy, tôi đoán một thông dịch viên sẽ là lựa chọn tốt nhất nếu tôi muốn mở rộng nó dễ dàng.
Nini Michaels

Cảm ơn bạn đã phản hồi, tôi đoán bắt đầu với liên kết đến CodeProject có thể là một ý tưởng tốt.
NoChance

2

Trừ khi bạn đặc biệt quan tâm đến việc viết trình phân tích cú pháp thực tế cho chính mình, tôi khuyên bạn nên xem một trong các khung trình tạo trình phân tích cú pháp. Đối với C, bạn có YACC hoặc Bison , nhưng nên có các lựa chọn thay thế khác cho các ngôn ngữ khác nếu bạn thích.

Những thứ này sẽ loại bỏ sự phức tạp của việc phân tích ngữ pháp phức tạp và cho phép bạn tập trung vào công việc bạn muốn làm. Tất nhiên điều này có thể là quá mức cần thiết cho ngữ pháp mà bạn đề xuất trong câu hỏi, nhưng vì bạn đề cập đến việc có tùy chọn mở rộng sang một ngữ pháp phức tạp hơn sau đó, ít nhất nên lấy cảm hứng từ các khung này.


1
Vấn đề với hầu hết các trình tạo phân tích cú pháp là các tạo phẩm của chúng là tĩnh và không dễ dàng cho vay để mở rộng. Tôi nghĩ OP sẽ được phục vụ tốt hơn với một cái gì đó giống như một công cụ quy tắc, trong đó "quy tắc" (từ khóa và cú pháp) được lưu trữ trong cấu trúc dữ liệu linh hoạt và được đánh giá sau mỗi lần nhập.
TMN

2

Những gì bạn đang mô tả rất gần với một ngôn ngữ ngăn xếp .

Ví dụ trong Factor, những gì bạn mô tả sẽ được thực hiện như thế nào

1
2 +
7 *
even? not

Hoặc bạn có thể định nghĩa các từ của riêng bạn và sau đó sử dụng chúng, như

: add ( x y -- sum ) + ;
: multiply ( x y -- product ) * ;
: odd? ( n -- ? ) even? not ;

Với những định nghĩa này, ví dụ trên trở thành

1
2 add
7 multiply
odd?

Thông thường các ngôn ngữ ngăn xếp là tầm thường để phân tích vì chúng sử dụng các từ đơn được phân tách không gian. Tôi đề nghị bạn nên xem Factor - nó có thể là những gì bạn muốn. Nó sẽ dễ dàng để xác định các từ mà xử lý bạn cần.

EDIT : Nếu bạn thực sự muốn thiết kế một ngôn ngữ tương tự, tôi khuyên bạn nên chơi với một trong số họ. Phân tích một ngôn ngữ ngăn xếp là chuyện nhỏ - bạn phân chia trên các khoảng trống và việc thực hiện xử lý ngây thơ rất dễ dàng: bạn chỉ cần quan tâm đến những gì xảy ra trên ngăn xếp.


Điều này nghe có vẻ khá dễ dàng, và một nơi tốt để bắt đầu. Cảm ơn!
Nini Michaels

1

Nhưng nếu tôi muốn mở rộng, tôi cần phải thực hiện chức năng như thế nào?

Bạn không nên. Khả năng mở rộng tạo ra rất nhiều sự phức tạp để đạt được rất ít. Điều đó nói rằng, bạn sẽ cần cung cấp một cái móc vào trạng thái hiện có. Một cách để xem trạng thái, sửa đổi trạng thái và cung cấp một cơ chế để trả về các kết quả khác (in ra màn hình). Bạn sẽ cần một cách để mã lõi khám phá các mô-đun, tải chúng và gửi lệnh cho chúng.

Tôi có sử dụng mẫu lệnh không?

Bạn có thể, nhưng nó có thể không thích hợp.

Bạn sẽ không lấy toàn bộ đầu vào và gửi đi để xử lý, mà thay vào đó, phân tích cú pháp đầu vào, gửi đến bộ xử lý chính xác và để nó thực hiện công việc của nó. Lệnh không thay đổi trong giao tiếp đó; vì vậy không có mẫu lệnh.

Tôi có xây dựng trình phân tích cú pháp / trình thông dịch đơn giản cho ngôn ngữ không?

Bạn sẽ cần một cái gì đó để xử lý việc phá vỡ đầu vào thành các mã thông báo. Đối với một giải pháp mở rộng, có lẽ bạn sẽ không làm được gì nhiều. Đối với một giải pháp được xác định rõ, có một cây phân tích đầy đủ sẽ cung cấp hiệu năng, xử lý lỗi và khả năng gỡ lỗi tốt hơn.

mà là một bộ xử lý danh sách (số)

Sau đó, có lẽ bạn nên xem xét ngôn ngữ Xử lý LISt . Sự kết hợp của mã và dữ liệu phải phù hợp với những gì bạn mô tả.


Cảm ơn về những đề nghị. Đối với LISP, tôi quen thuộc với nó và thậm chí còn quen thuộc hơn với Haskell, người đã truyền cảm hứng cho tôi với ý tưởng này. Tuy nhiên, mặc dù tôi có thể phát minh lại bánh xe một chút, tôi muốn làm bẩn tay mình bằng các lệnh xử lý và diễn giải chúng. Vì vậy, nó cũng có một mục đích giáo dục bên cạnh việc "xử lý danh sách" thực tế :)
Nini Michaels

@NiniMichaels chắc chắn, nhưng theo như một thiết kế cho khả năng mở rộng, sử dụng tổ chức / chuỗi mã / dữ liệu của lisp không phải là một lựa chọn tồi.
Telastyn
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.