Tôi đang cố gắng giữ cho trình phân tích cú pháp và trình phân tích cú pháp riêng biệt, dựa trên lời khuyên mơ hồ của cuốn sách Phân tích ngôn ngữ Prolog và tự nhiên, thực sự không đi sâu vào chi tiết về lexing/tokenizing. Vì vậy, tôi cho nó một shot và nhìn thấy một số vấn đề nhỏ mà chỉ cho tôi rằng có cái gì đó rõ ràng tôi đang mất tích.Prolog DCG: Viết ngôn ngữ lập trình lexer
Tất cả các trình phân tích cú pháp nhỏ của tôi dường như không hoạt động; tại thời điểm này đây là một đoạn mã của tôi:
:- use_module(library(dcg/basics)).
operator('(') --> "(". operator(')') --> ")".
operator('[') --> "[". operator(']') --> "]".
% ... etc.
keyword(array) --> "array".
keyword(break) --> "break".
% ... etc.
Đó là một chút lặp đi lặp lại nhưng có vẻ như nó hoạt động. Sau đó, tôi có một số thứ mà tôi không hoàn toàn yêu thương và tôi hoan nghênh đề xuất về, nhưng dường như để làm việc:
Nguyên tắc chính cho tokenizer tôi là thế này:
token(X) --> whites, (keyword(X) ; operator(X) ; id(X) ; int(X) ; string(X)).
Đó là chưa hoàn hảo; Tôi sẽ thấy int
được phân tích cú pháp thành in,id(t)
vì keyword(X)
xuất hiện trước id(X)
. Vì vậy, tôi đoán đó là câu hỏi đầu tiên.
Câu hỏi lớn hơn tôi có là tôi không thấy cách tích hợp đúng các nhận xét vào tình huống này. Tôi đã thử các cách sau:
skipAhead --> [].
skipAhead --> (comment ; whites), skipAhead.
comment --> "/*", anything, "*/".
anything --> [].
anything --> [_], anything.
token(X) --> skipAhead, (keyword(X) ; operator(X) ; id(X) ; int(X) ; string(X)).
Điều này dường như không hoạt động; các phân tích cú pháp trả về (và tôi nhận được nhiều phân tích cú pháp) dường như không xóa nhận xét. Tôi lo lắng rằng quy tắc bình luận của tôi là không cần thiết không hiệu quả và có thể gây ra rất nhiều backtracking không cần thiết. Tôi cũng lo lắng rằng whites//0
từ dcg/khái niệm cơ bản là xác định; Tuy nhiên, một phần của phương trình dường như hoạt động, nó chỉ tích hợp nó với nhận xét bỏ qua mà dường như không.
Lưu ý cuối cùng, tôi không thấy cách xử lý các lỗi phân tích cú pháp ngược lại cho người dùng có thông tin dòng/cột từ đây. Nó cảm thấy như tôi sẽ phải theo dõi và thread thông qua một số loại dòng/cột thông tin hiện tại và viết nó vào các thẻ và sau đó có thể cố gắng xây dựng lại dòng nếu tôi muốn làm một cái gì đó tương tự như cách llvm hiện nó. Đó là công bằng hay là có một "thực hành được đề nghị" ở đó?
Toàn bộ mã có thể được tìm thấy in this haste.
Lý do chính đáng cho sự lo lắng. 'comment // 0':' cụm từ (bình luận, "/ **/* /") 'là đúng, nhưng thay vì thất bại. – false