Các loại dịch giả. chuỗi phù hợp với tình huống A:_b, với mọi quy tắc A:b. Mục đích của khóa học này là phát triển một dịch giả giáo dục từ một ngôn ngữ văn bản cấp cao đơn giản hóa nhất định

Người phiên dịch (English Translator – phiên dịch viên) là một chương trình dịch thuật. Nó chuyển đổi một chương trình được viết bằng một trong các ngôn ngữ cấp độ cao, thành một chương trình bao gồm các lệnh máy. Người dịch cũng thường chẩn đoán lỗi, tạo từ điển mã định danh, tạo văn bản chương trình để in, v.v. Ngôn ngữ mà chương trình đầu vào được trình bày được gọi là ngôn ngữ nguồn và chính chương trình đó được gọi là mã nguồn. Ngôn ngữ đầu ra được gọi là ngôn ngữ đích hoặc mã đối tượng.

Nhìn chung, khái niệm dịch thuật không chỉ áp dụng cho các ngôn ngữ lập trình mà còn cho các ngôn ngữ khác - cả ngôn ngữ máy tính chính thức (như ngôn ngữ đánh dấu như HTML) và ngôn ngữ tự nhiên (tiếng Nga, tiếng Anh, v.v.).

Các loại dịch giả

    Hộp thoại. Cung cấp việc sử dụng ngôn ngữ lập trình ở chế độ chia sẻ thời gian.

    Định hướng cú pháp (điều khiển cú pháp). Nhận làm đầu vào mô tả cú pháp và ngữ nghĩa của ngôn ngữ và văn bản trong ngôn ngữ được mô tả, được dịch theo mô tả đã cho.

    Đường chuyền đơn. Tạo thành một mô-đun đối tượng trong một lần xem tuần tự của chương trình nguồn.

    Nhiều đường chuyền. Tạo thành một mô-đun đối tượng qua một số khung nhìn của chương trình nguồn.

    Tối ưu hóa. Thực hiện tối ưu hóa mã trong mô-đun đối tượng được tạo.

    Bài kiểm tra. Một tập hợp các lệnh macro hợp ngữ cho phép bạn thiết lập các quy trình gỡ lỗi khác nhau trong các chương trình được viết bằng hợp ngữ.

    Mặt sau. Đối với một chương trình bằng mã máy, nó tạo ra một chương trình tương đương bằng bất kỳ ngôn ngữ lập trình nào (xem: trình dịch ngược, trình dịch ngược).

Trình dịch được thực hiện như trình biên dịch hoặc trình thông dịch. Về mặt thực hiện công việc, trình biên dịch và trình thông dịch khác nhau đáng kể.

Trình biên dịch (Trình biên dịch tiếng Anh - trình biên dịch, trình thu thập) đọc toàn bộ chương trình, dịch nó và tạo ra một phiên bản hoàn chỉnh của chương trình bằng ngôn ngữ máy, sau đó được thực thi. Thông tin đầu vào của trình biên dịch (mã nguồn) là mô tả thuật toán hoặc chương trình bằng ngôn ngữ hướng vấn đề và đầu ra của trình biên dịch là mô tả tương đương của thuật toán trong ngôn ngữ hướng máy (mã đối tượng).

Các loại trình biên dịch

    Vector hóa. Dịch mã nguồn thành mã máy trên máy tính được trang bị bộ xử lý vector.

    Linh hoạt. Được thiết kế theo kiểu mô-đun, được điều khiển bởi các bảng và được lập trình bằng ngôn ngữ cấp cao hoặc được triển khai bằng trình biên dịch các trình biên dịch.

    Hộp thoại. Xem: dịch đối thoại.

    Tăng dần. Truyền lại các đoạn chương trình và phần bổ sung vào nó mà không cần biên dịch lại toàn bộ chương trình.

    Giải thích (từng bước). Tuần tự thực hiện việc biên dịch độc lập từng câu lệnh (lệnh) riêng lẻ của chương trình nguồn.

    Trình biên dịch của các trình biên dịch. Trình dịch chấp nhận mô tả chính thức của ngôn ngữ lập trình và tạo trình biên dịch cho ngôn ngữ đó.

    Gỡ lỗi. Loại bỏ một số loại lỗi cú pháp.

    Người dân. Liên tục ở trong bộ nhớ truy cập tạm thời và có sẵn để tái sử dụng cho nhiều nhiệm vụ.

    Tự biên soạn. Được viết bằng cùng ngôn ngữ mà chương trình phát sóng được thực hiện.

    Phổ quát. Dựa trên mô tả chính thức về cú pháp và ngữ nghĩa của ngôn ngữ đầu vào. Các thành phần của trình biên dịch như vậy là: kernel, bộ tải cú pháp và ngữ nghĩa.

Translator (eng. dịch giả - dịch giả) là một chương trình dịch Nó chuyển đổi một chương trình được viết bằng một trong các ngôn ngữ lập trình thành tệp nhị phân của chương trình bao gồm các lệnh máy hoặc thực hiện trực tiếp các hành động của chương trình.

Trình dịch được triển khai dưới dạng trình biên dịch, trình thông dịch, bộ tiền xử lý và trình mô phỏng. Về mặt thực hiện công việc, trình biên dịch và trình thông dịch khác nhau đáng kể.

Trình biên dịch (eng. trình biên dịch - trình biên dịch, trình thu thập)- đọc toàn bộ chương trình, dịch nó và tạo một phiên bản hoàn chỉnh của chương trình bằng ngôn ngữ máy, tức là một tệp nhị phân chứa danh sách các lệnh máy. Một tệp nhị phân có thể được thực thi, thư viện, đối tượng), nó được hệ điều hành thực thi mà không cần sự tham gia của trình biên dịch.

Thông dịch viên (eng. thông dịch viên - thông dịch viên, biên dịch viên)— dịch từng dòng chương trình (mỗi lần một câu lệnh) thành mã máy (lệnh bộ xử lý, hệ điều hành, môi trường khác), thực thi câu lệnh đã dịch (dòng chương trình), sau đó chuyển sang dòng văn bản chương trình tiếp theo. Trình thông dịch không tạo ra các tập tin thực thi; nó tự thực hiện tất cả các hành động được viết trong văn bản của chương trình nguồn.

Khi một chương trình được biên dịch, cả chương trình nguồn lẫn trình biên dịch đều không cần thiết nữa. Đồng thời, chương trình được trình thông dịch xử lý phải được dịch lại sang ngôn ngữ máy mỗi khi khởi chạy chương trình.

Các chương trình biên dịch chạy nhanh hơn, nhưng các chương trình được thông dịch thì dễ sửa và thay đổi hơn.

Mỗi ngôn ngữ cụ thể được định hướng theo hướng biên dịch hoặc giải thích - tùy thuộc vào mục đích mà nó được tạo ra. Ví dụ, Pascal thường được sử dụng để giải các bài toán khá phức tạp trong đó tốc độ chương trình là quan trọng. Do đó, ngôn ngữ này thường được triển khai bằng trình biên dịch.

Mặt khác, BASIC được tạo ra như một ngôn ngữ dành cho những người mới lập trình, những người mà việc thực thi chương trình từng dòng một có những lợi thế không thể phủ nhận.

Đôi khi có cả trình biên dịch và trình thông dịch cho cùng một ngôn ngữ. Trong trường hợp này, bạn có thể sử dụng trình thông dịch để phát triển và kiểm tra chương trình, sau đó biên dịch chương trình đã gỡ lỗi để cải thiện tốc độ thực thi của chương trình.

Bộ tiền xử lý là trình dịch từ ngôn ngữ lập trình này sang ngôn ngữ lập trình khác mà không cần tạo tệp thực thi hoặc thực thi chương trình.

Bộ tiền xử lý thuận tiện cho việc mở rộng khả năng của ngôn ngữ và sự thuận tiện của việc lập trình bằng cách sử dụng, ở giai đoạn viết chương trình, một phương ngữ thân thiện hơn với con người của ngôn ngữ lập trình và dịch nó bằng bộ tiền xử lý sang văn bản của ngôn ngữ lập trình tiêu chuẩn , có thể được biên dịch bởi một trình biên dịch tiêu chuẩn.

Giả lập- phần mềm và/hoặc phần cứng hoạt động trong một hệ điều hành mục tiêu và nền tảng phần cứng nhất định, được thiết kế để thực thi các chương trình được tạo ra trong hệ điều hành khác hoặc chạy trên một thiết bị khác với thiết bị mục tiêu phần cứng, nhưng cho phép thực hiện các hoạt động tương tự trong môi trường đích như trong hệ thống mô phỏng.

Các ngôn ngữ mô phỏng bao gồm các hệ thống như Java, .Net, Mono, trong đó, ở giai đoạn tạo chương trình, nó được biên dịch thành mã byte đặc biệt và thu được tệp nhị phân, phù hợp để thực thi trong mọi môi trường điều hành và phần cứng, và mã byte kết quả được thực thi trên máy đích bằng cách sử dụng trình thông dịch đơn giản và nhanh chóng (máy ảo).

Trình lắp ráp lại, trình tháo rời- một công cụ phần mềm được thiết kế để giải mã mã nhị phân và trình bày nó dưới dạng văn bản tập hợp hoặc văn bản của ngôn ngữ lập trình khác, cho phép bạn phân tích thuật toán của chương trình nguồn và sử dụng văn bản kết quả để sửa đổi chương trình cần thiết, chẳng hạn , thay đổi địa chỉ thiết bị bên ngoài, truy cập vào hệ thống và tài nguyên mạng, xác định các chức năng ẩn của mã nhị phân (ví dụ: virus máy tính hoặc chương trình độc hại khác: Trojan, worm, keylogger, v.v.).

đến các thuật toán thuật toán, cấu trúc dữ liệu và lập trình chương trình công nghệ DBMS Ya&MP 3GL 4GL 5GL.

Bạn có biết không, Cái gì trừu tượng hóa thông qua tham số hóa là một kỹ thuật lập trình cho phép, bằng cách sử dụng các tham số, biểu diễn một tập hợp hầu như không giới hạn các phép tính khác nhau bằng một chương trình, đây là sự trừu tượng hóa của các tập hợp này.

Người dịch

Vì máy tính không thể hiểu được văn bản của chương trình viết bằng Pascal nên nó cần được dịch sang ngôn ngữ máy. Việc dịch chương trình từ ngôn ngữ lập trình sang ngôn ngữ mã máy được gọi là phát tin (dịch - dịch), nhưng nó được thực hiện chương trình đặc biệtđài truyền hình.

Có ba loại trình dịch: trình thông dịch, trình biên dịch và trình biên dịch.

Thông dịch viênđược gọi là trình dịch thực hiện việc xử lý và thực thi từng người vận hành (theo lệnh) của chương trình nguồn.

Trình biên dịch chuyển đổi (dịch) toàn bộ chương trình thành một mô-đun bằng ngôn ngữ máy, sau đó chương trình được ghi vào bộ nhớ máy tính và chỉ sau đó được thực thi.

Thợ lắp ráp dịch chương trình viết bằng hợp ngữ (mã tự động) sang chương trình bằng ngôn ngữ máy.

Bất kỳ người dịch nào cũng giải quyết các nhiệm vụ chính sau:

Phân tích chương trình đã dịch, đặc biệt là xác định xem nó có chứa lỗi cú pháp hay không;

Tạo chương trình đầu ra (thường được gọi là đối tượng hoặc chương trình làm việc) bằng ngôn ngữ lệnh máy tính (trong một số trường hợp, trình dịch tạo chương trình đầu ra bằng ngôn ngữ trung gian, ví dụ: ngôn ngữ hợp ngữ);

Cấp phát bộ nhớ cho chương trình đầu ra (trong trường hợp đơn giản nhất, việc này bao gồm việc gán từng đoạn chương trình, biến, hằng, mảng và các đối tượng khác địa chỉ bộ nhớ riêng của chúng).

Giới thiệu về .Net và Sharp

Lập trình viên viết chương trình bằng ngôn ngữ mà lập trình viên hiểu và máy tính chỉ thực thi các chương trình được viết bằng ngôn ngữ mã máy. Bộ công cụ để viết, chỉnh sửa và chuyển đổi chương trình thành mã máy và thực thi nó được gọi là môi trường phát triển.

Môi trường phát triển bao gồm:

    Trình soạn thảo văn bản để nhập và chỉnh sửa văn bản chương trình

    Trình biên dịch để dịch chương trình sang ngôn ngữ lệnh máy

    Công cụ gỡ lỗi và khởi chạy chương trình để thực thi

    Thư viện được chia sẻ với các thành phần phần mềm có thể tái sử dụng

    Hệ thống trợ giúp, v.v.

Nền tảng .NET do Microsoft phát triển không chỉ bao gồm môi trường phát triển đa ngôn ngữ có tên Visual Studio .NET mà còn nhiều công cụ khác, chẳng hạn như hỗ trợ cơ sở dữ liệu, E-mail và vân vân.

Các nhiệm vụ quan trọng nhất trong việc phát triển phần mềm hiện đại là:

    Tính di động - khả năng chạy trên các loại máy tính khác nhau

    Bảo mật - không thể thực hiện các hành động trái phép

    Độ tin cậy - hoạt động không có lỗi trong các điều kiện nhất định

    Sử dụng các thành phần có sẵn để tăng tốc độ phát triển

    Tương tác giữa các ngôn ngữ - việc sử dụng một số ngôn ngữ lập trình.

Tất cả các tác vụ này được giải quyết trong nền tảng .NET.

Để đảm bảo tính di động, trình biên dịch nền tảng không dịch chương trình sang mã máy mà sang ngôn ngữ trung gian MSIL (Ngôn ngữ trung gian của Microsoft) hoặc đơn giản sang IL. IL không chứa các lệnh phụ thuộc vào hệ điều hành hoặc loại máy tính. Chương trình IL được thực thi bởi CLR (Thời gian chạy ngôn ngữ chung), vốn dành riêng cho từng loại máy tính. Việc dịch chương trình IL sang mã máy của một máy tính cụ thể được thực hiện bởi trình biên dịch JIT (Just In Time).

Sơ đồ thực hiện chương trình trên nền tảng .NET được hiển thị trong Hình 1.

Trình biên dịch tạo một tập hợp chương trình - một tệp có phần mở rộng . exe hoặc . dll, chứa mã IL. Việc thực thi chương trình được tổ chức bởi môi trường CRL, môi trường này giám sát tính hợp lệ của các hoạt động, thực hiện cấp phát và dọn dẹp bộ nhớ cũng như xử lý các lỗi thực thi. Điều này đảm bảo sự an toàn và độ tin cậy của các chương trình.

Cái giá phải trả cho những ưu điểm này là hiệu suất chương trình giảm và nhu cầu cài đặt .NET trên máy tính để thực thi các chương trình làm sẵn.

Vì vậy, .NET là một nền tảng lập trình.

C# (Biển sắc nét) là một trong những ngôn ngữ lập trình của nền tảng .NET. Nó được bao gồm trong Visual Studio - Visual Studio.NET (Phiên bản 2008, 2010, 2012). Ngoài C#, Visual Studio.NET còn có Visual Basic.NET và Visual C++.

Một trong những lý do để Microsoft phát triển ngôn ngữ mới là tạo ra ngôn ngữ hướng thành phần cho nền tảng .Nền tảng NET.

Hình 1 Sơ đồ thực hiện chương trình trong .NET

NET Framework bao gồm hai phần:

    Đầu tiên, nó bao gồm một thư viện khổng lồ gồm các lớp có thể được gọi từ các chương trình C#. Có rất nhiều lớp (khoảng vài nghìn). Điều này giúp loại bỏ sự cần thiết phải tự viết mọi thứ. Do đó, lập trình trong C# liên quan đến việc viết mã của riêng bạn để gọi các lớp được lưu trữ trong .NET Framework nếu cần.

    Thứ hai, nó bao gồm môi trường .NET Runtime, môi trường này kiểm soát việc khởi chạy và vận hành các chương trình được tạo sẵn.

Nền tảng .NET là một môi trường mở - các nhà phát triển bên thứ ba đã tạo ra hàng chục trình biên dịch cho .NET cho các ngôn ngữ Ada, COBOL, Fortran, Lisp, Oberon, Perl, Python, v.v.

Nền tảng .NET đang tích cực phát triển - các phiên bản mới của nền tảng này đang được phát hành. Sử dụng thực đơn Dự án Của cải Tìm hiểu phiên bản nền tảng .NET bạn đang sử dụng.

Về lý thuyết, một chương trình .NET có thể chạy trên bất kỳ hệ điều hành nào được cài đặt .NET. Nhưng trên thực tế, nền tảng chính thức duy nhất cho việc này là hệ điều hành Windows. Tuy nhiên, có những triển khai .NET không chính thức cho Linux giống Unix, Mac OS X và các phiên bản khác (Mono là một dự án .NET Framework dựa trên phiên bản .NET Framework miễn phí. phần mềm).

Từ liễu kiếm

Từ rapier trong chữ cái tiếng Anh (phiên âm) - rapira

Từ rapier gồm có 6 chữ cái: a a và p r r

Ý nghĩa của từ rapier. Một rapper là gì?

Rapier (Rapier của Đức, từ rapière của Pháp, ban đầu là Espadas Roperas của Tây Ban Nha - nghĩa đen là “kiếm dùng cho quần áo” (nghĩa là không phải dùng để mặc áo giáp), bị bóp méo trong tiếng Pháp là la rapiere) - một loại vũ khí có lưỡi sắc bén, một loại kiếm...

vi.wikipedia.org

Rapier (Rapier của Đức, từ rapière của Pháp), một vũ khí xuyên thấu thể thao, bao gồm một lưỡi kiếm đàn hồi bằng thép và một chuôi kiếm (một tấm bảo vệ và tay cầm hình chiếc cốc).

TSB. - 1969-1978

RAPIER (Rapier của Đức, từ rapiere của Pháp). Vũ khí xuyên thấu thể thao. Bao gồm một lưỡi dao và chuôi kiếm bằng thép linh hoạt (bảo vệ và tay cầm hình cốc). Lưỡi dao có tiết diện hình chữ nhật, thon dần về phía trên...

Bách khoa toàn thư Olympic. - 2006

RAPIRA, Trình thông dịch, Biên tập, Lưu trữ Poplan thích ứng mở rộng, là một ngôn ngữ lập trình giáo dục và công nghiệp. Được phát triển vào đầu những năm 80 ở Liên Xô. Kiếm là một phương tiện...

Bách khoa toàn thư về ngôn ngữ lập trình

Thanh kiếm (SAM)

Rapier là hệ thống tên lửa đất đối không được Lực lượng Vũ trang Anh phát triển cho Lực lượng Không quân Hoàng gia. Nó đang phục vụ trong quân đội Australia, Anh, Indonesia, Singapore, Thổ Nhĩ Kỳ, Malaysia và Thụy Sĩ.

vi.wikipedia.org

Chiến đấu bằng liễu kiếm

Rapier chiến đấu - (từ rapiere của Pháp) - X.0 lưỡi dài xuyên thấu, xuyên thấu. có tay cầm, được biết đến ở châu Âu từ nửa sau thế kỷ 17. Bao gồm một lưỡi thép thẳng, phẳng hoặc có cạnh với một mũi nhọn (để đấu tay đôi R.)…

liễu kiếm thể thao

THỂ THAO RAPIRA - một loại vũ khí có lưỡi thể thao, bao gồm một lưỡi dao hình chữ nhật linh hoạt theo mặt cắt ngang và một tay cầm có thể tháo rời với tấm bảo vệ hình chiếc cốc tròn.

vũ khí.slovaronline.com

Một thanh liễu kiếm thể thao là một loại vũ khí có lưỡi thể thao bao gồm một lưỡi kiếm hình chữ nhật linh hoạt và một tay cầm có thể tháo rời với tấm bảo vệ hình chiếc cốc tròn.

Petrov A. Từ điển vũ khí và áo giáp có lưỡi

Rapier (ngôn ngữ lập trình)

RAPIRA - Trình thông dịch, Trình soạn thảo, Lưu trữ Poplan thích ứng mở rộng - ngôn ngữ lập trình thủ tục. Được phát triển vào đầu những năm 80 ở Liên Xô như một phương tiện chuyển đổi từ ngôn ngữ đơn giản(đặc biệt, ngôn ngữ giáo dục Robik)…

vi.wikipedia.org

Đấu kiếm tại Thế vận hội Mùa hè 1896 - giấy bạc

Nội dung đấu kiếm bằng giấy bạc nam tại Thế vận hội Mùa hè 1896 diễn ra vào ngày 7 tháng 4.

Biên dịch, biên dịch, phiên dịch

Tám vận động viên từ hai quốc gia đã tham gia. Đầu tiên họ thi đấu theo hai nhóm gồm bốn vận động viên...

vi.wikipedia.org

Đấu kiếm tại Thế vận hội Mùa hè 1900 - giấy bạc

Môn đấu kiếm lá bạc nam tại Thế vận hội Mùa hè 1900 diễn ra từ ngày 14 đến 19 và 21 tháng 5. 54 vận động viên từ 10 quốc gia đã tham gia.

vi.wikipedia.org

Ngôn ngữ Nga

Rapier.

Từ điển chính tả hình thái. - 2002

Đấu kiếm tại Thế vận hội Mùa hè 1900 - đấu kiếm giữa các bậc thầy

Nội dung đấu kiếm lá giữa các võ sĩ nam tại Thế vận hội Mùa hè 1900 diễn ra từ ngày 22 đến 25 và từ ngày 27 đến ngày 28 tháng 5.

59 vận động viên từ bảy quốc gia đã tham gia.

vi.wikipedia.org

Ví dụ sử dụng cho rapier

Thanh kiếm được làm theo cách không thể đi vào bên trong; mức tối đa có thể còn lại là một vết bầm tím.

Dựa trên dấu hiệu trên tay cầm của thanh kiếm, các đặc vụ đến câu lạc bộ đấu kiếm và phát hiện ra rằng thanh kiếm đã bị đánh cắp ở đó một năm trước.

Bài giảng: Tiêu chuẩn và giấy phép phần mềm

Tiêu chuẩn Họ UNIX. Tiêu chuẩn ngôn ngữ lập trình C. Định nghĩa giao diện hệ thống V (SVID). Ủy ban POSIX. X/Mở, OSF và Nhóm mở. Giấy phép cho phần mềm và tài liệu.
Nội dung

  • 3.1. Tiêu chuẩn gia đình UNIX
    • Tiêu chuẩn ngôn ngữ lập trình C
    • Định nghĩa giao diện hệ thống V (SVID)
    • Ủy ban POSIX
    • X/Mở, OSF và Nhóm mở
  • 3.2. Giấy phép phần mềm và tài liệu

3.1. Tiêu chuẩn gia đình UNIX

Lý do cho sự xuất hiện của các tiêu chuẩn cho hệ điều hành UNIX là vì nó được chuyển sang nhiều nền tảng phần cứng. Các phiên bản đầu tiên của nó chạy trên phần cứng PDP, nhưng vào năm 1976 và 1978, hệ thống này đã được chuyển sang Interdata và VAX. Từ năm 1977 đến năm 1981, hai nhánh cạnh tranh đã hình thành: AT&T UNIX và BSD. Có lẽ mục tiêu phát triển các tiêu chuẩn là khác nhau. Một trong số đó là hợp pháp hóa tính ưu việt của phiên bản của nó, và thứ hai là đảm bảo tính di động của hệ thống và các chương trình ứng dụng giữa các nền tảng phần cứng khác nhau. Về vấn đề này, họ nói về tính di động của chương trình. Các thuộc tính như vậy liên quan đến cả mã nguồn của chương trình và chương trình thực thi.

Tài liệu sau đây được trình bày theo thứ tự thời gian xuất hiện của các tiêu chuẩn.

Tiêu chuẩn ngôn ngữ lập trình C

Tiêu chuẩn này không áp dụng trực tiếp cho UNIX. Nhưng vì C là nền tảng cho cả họ này và các hệ điều hành khác nên chúng tôi sẽ đề cập đến tiêu chuẩn của ngôn ngữ lập trình này. Nó bắt đầu với việc xuất bản ấn bản đầu tiên của cuốn sách của B. Kernighan và D. Ritchie vào năm 1978. Tiêu chuẩn này thường được gọi là K&R. Các lập trình viên đằng sau công việc này đã làm việc trên UNIX với Ken Thompson. Hơn nữa, người đầu tiên trong số họ đã đề xuất tên của hệ thống và người thứ hai đã phát minh ra ngôn ngữ lập trình này. Văn bản tương ứng có sẵn trên Internet [ 45 ].

Tuy nhiên, tiêu chuẩn công nghiệp cho ngôn ngữ lập trình C được ANSI phát hành vào năm 1989 và được đặt tên là X3. 159 – 1989. Đây là những gì được viết về tiêu chuẩn này [ 46 ]:

“Tiêu chuẩn được thông qua để cải thiện tính di động của các chương trình được viết bằng ngôn ngữ C giữa các loại hệ điều hành khác nhau. Do đó, ngoài cú pháp và ngữ nghĩa của ngôn ngữ C, tiêu chuẩn còn bao gồm các đề xuất về nội dung của thư viện tiêu chuẩn. hỗ trợ cho tiêu chuẩn ANSI C được biểu thị bằng tên tượng trưng được xác định trước _STDC.”

Năm 1988, dựa trên tiêu chuẩn ngôn ngữ lập trình này, ấn bản thứ hai của cuốn sách về C của Kernighan và Ritchie đã được phát hành. sản phẩm phần mềmđể phát triển các chương trình bằng ngôn ngữ C, họ có thể tạo thư viện của riêng mình và thậm chí mở rộng một chút thành phần của các công cụ ngôn ngữ khác.

^ Định nghĩa giao diện hệ thống V (SVID)

Một hướng khác trong việc phát triển các tiêu chuẩn UNIX là do không chỉ những người đam mê mới nghĩ đến việc tạo ra các “tiêu chuẩn”. Các nhà phát triển chính của hệ thống, với sự xuất hiện của nhiều “biến thể”, đã quyết định xuất bản tài liệu của riêng họ. Do đó, các tiêu chuẩn được tạo ra bởi USG, tổ chức đã ghi lại các phiên bản UNIX của AT&T kể từ khi công ty con đó được thành lập để tạo ra hệ điều hành. Tài liệu đầu tiên xuất hiện vào năm 1984 dựa trên SVR2. Nó được gọi là SVID (Định nghĩa giao diện hệ thống V). Phiên bản bốn tập đã được phát hành sau khi phát hành SVR4. Các tiêu chuẩn này được bổ sung bởi một bộ chương trình thử nghiệm SVVS (Bộ xác minh hệ thống V). Mục đích chính của những công cụ này là cho phép các nhà phát triển đánh giá liệu hệ thống của họ có đủ điều kiện cho tên System V [ 14 ].

Lưu ý rằng tình huống với tiêu chuẩn SVID có phần giống với tiêu chuẩn của ngôn ngữ lập trình C. Cuốn sách do các tác giả của ngôn ngữ lập trình này xuất bản là một trong những tiêu chuẩn, nhưng không phải là tiêu chuẩn duy nhất. Tiêu chuẩn C, được phát hành sau đó, là kết quả của công việc tập thể, đã vượt qua giai đoạn thảo luận của công chúng và dường như có thể khẳng định vai trò dẫn đầu trong danh sách các tiêu chuẩn. Tương tự như vậy, SVVS là một tập hợp các bài kiểm tra cho phép bạn đánh giá liệu một hệ thống có xứng đáng với tên System V hay không, chỉ là một trong các phiên bản của UNIX. Điều này không tính đến tất cả kinh nghiệm phát triển hệ điều hành từ các nhà sản xuất khác nhau.

Ủy ban POSIX

Công việc thiết kế các tiêu chuẩn UNIX được bắt đầu bởi một nhóm những người đam mê vào năm 1980. Mục tiêu được xây dựng để xác định chính thức các dịch vụ mà hệ điều hành cung cấp cho các ứng dụng. Tiêu chuẩn giao diện phần mềm này đã trở thành nền tảng của tài liệu POSIX (Giao diện hệ điều hành di động cho môi trường máy tính - giao diện hệ điều hành di động cho môi trường máy tính) [ 14 ]. Nhóm làm việc POSIX đầu tiên được thành lập vào năm 1985 từ ủy ban/usr/nhóm tiêu chuẩn định hướng UNIX, còn được gọi là UniForum [ 47 ]. Tên POSIX được đề xuất bởi người sáng lập GNU Richard Stallman.

Các phiên bản đầu tiên của POSIX đã xác định một bộ Dịch vụ hệ thống, cần thiết cho hoạt động của các chương trình ứng dụng được mô tả trong giao diện được chỉ định cho ngôn ngữ C (giao diện cuộc gọi hệ thống). Những ý tưởng trong đó đã được ủy ban ANSI (Viện Tiêu chuẩn Quốc gia Hoa Kỳ) sử dụng khi tạo ra tiêu chuẩn ngôn ngữ C được đề cập trước đó. Bộ chức năng ban đầu có trong các phiên bản đầu tiên dựa trên AT&T UNIX (phiên bản SVR4 [ 48 ]). Nhưng trong tương lai, các thông số kỹ thuật của tiêu chuẩn POSIX sẽ được tách biệt khỏi hệ điều hành cụ thể này. Cách tiếp cận để tổ chức một hệ thống dựa trên nhiều chức năng hệ thống cơ bản không chỉ được áp dụng trong UNIX (ví dụ: WinAPI của Microsoft).

Năm 1988, tiêu chuẩn 1003.1 - 1988 được xuất bản, định nghĩa API (Giao diện lập trình ứng dụng). Hai năm sau, phiên bản mới của tiêu chuẩn IEEE 1003.1 - 1990 đã được thông qua. quy tắc chung giao diện lập trình cho cả các cuộc gọi hệ thống và chức năng thư viện. Các bổ sung bổ sung thêm cho nó đã được phê duyệt, xác định các dịch vụ cho hệ thống thời gian thực, luồng POSIX, v.v. Tiêu chuẩn POSIX 1003.2 - 1992 rất quan trọng - xác định trình thông dịch lệnh và các tiện ích.

Có bản dịch [ 1 ] hai nhóm tài liệu này được gọi là: POSIX.1 (giao diện chương trình ứng dụng) và POSIX.2 (trình thông dịch lệnh và tiện ích - giao diện người dùng). Bản dịch được đề cập bao gồm ba chương: khái niệm cơ bản, dịch vụ hệ thống và tiện ích. chương " Dịch vụ hệ thống" được chia thành nhiều phần, mỗi phần nhóm các dịch vụ có chức năng tương tự nhau. Ví dụ: trong một trong các phần "I/O cơ bản", phần thứ bảy, dành cho các hoạt động thư mục, mô tả ba chức năng (opendir, readdir và closeir) . Chúng được xác định trong bốn đoạn: "Cú pháp", "Mô tả", "Giá trị trả về" và "Lỗi".

Đối với những người đã quen thuộc với ngôn ngữ lập trình thuật toán C, đây là một ví dụ về các đoạn mô tả.

Ngôn ngữ lập trình, trình biên dịch, trình biên dịch và trình thông dịch

Trên thực tế, mô tả này đưa ra ý tưởng về cách chỉ định "Giao diện cuộc gọi hệ thống". Trong phần "Cú pháp" về hàm readdir, có các dòng sau:

#bao gồm

#bao gồm

struct dirent *readdir(DIR *dirp);

Đoạn thứ hai (“Mô tả”) có nội dung sau:

"Các kiểu và cấu trúc dữ liệu được sử dụng trong định nghĩa thư mục được xác định trong tệp dirent.h. Thành phần bên trong của các thư mục được xác định theo cách thực hiện. Khi đọc bằng hàm readdir, một đối tượng thuộc loại struct dirent được hình thành, chứa trường mảng ký tự d_name, chứa NUL kết thúc bằng ký tự tên địa phương tài liệu.

Readdir đọc phần tử thư mục hiện tại và đặt con trỏ vị trí tới phần tử tiếp theo. Thư mục mở được chỉ định bởi con trỏ dirp. Phần tử chứa tên trống, bị bỏ qua."

Và đây là những gì được đưa ra trong đoạn “Giá trị trả về”:

"Readdir, sau khi hoàn thành thành công, trả về một con trỏ tới một đối tượng thuộc loại struct dirent chứa phần tử thư mục đã đọc. Phần tử đã đọc có thể được lưu trữ trong bộ nhớ tĩnh và bị ghi đè bởi lệnh gọi tiếp theo được áp dụng cho cùng một thư mục đang mở. Gọi readdir cho các thư mục mở khác nhau không trùng lặp với thông tin đã đọc. Nếu xảy ra lỗi hoặc đến cuối tệp, một con trỏ rỗng sẽ được trả về."

Đoạn "Lỗi trong tiêu chuẩn" nêu rõ như sau:

"Readdir và closeir gặp lỗi. Dirp không phải là con trỏ tới thư mục đang mở."

Ví dụ này cho thấy các dịch vụ được cung cấp bởi một ứng dụng được mô tả như thế nào. Các yêu cầu đối với hệ điều hành (triển khai) là nó “...phải hỗ trợ tất cả các yêu cầu tiện ích, chức năng, tệp tiêu đề đảm bảo hành vi được chỉ định trong tiêu chuẩn. Hằng số _POSIX_VERSION có giá trị 200112L [ 49 ]".

Trên thế giới công nghệ máy tính Có một cụm từ như vậy: "lập trình POSIX". Điều này có thể học được từ các hướng dẫn về hệ điều hành và lập trình hệ thống UNIX khác nhau (ví dụ: [ 5 ]). Có một cuốn sách riêng với tựa đề này [ 3 ]. Lưu ý rằng trong lời nói đầu của cuốn sách này có nói rằng nó mô tả "... một tiêu chuẩn gấp ba... ", vì nó dựa trên phiên bản mới nhất POSIX 2003, dựa trên ba tiêu chuẩn: IEEE Std 1003.1, tiêu chuẩn kỹ thuật của Nhóm Mở và ISO/IEC 9945.

Làm cách nào bạn có thể xác minh rằng một hệ thống cụ thể tuân thủ tiêu chuẩn POSIX? Việc chính thức hóa một câu hỏi như vậy không đơn giản như thoạt nhìn. Các phiên bản hiện đại cung cấp 4 loại tuân thủ (bốn ý nghĩa ngữ nghĩa của từ “tuân thủ”: đầy đủ, quốc tế, quốc gia, mở rộng).

Các tài liệu đang được xem xét cung cấp danh sách hai loại công cụ giao diện: bắt buộc (nếu có thể, nó được coi là nhỏ gọn) và tùy chọn. Cái sau phải được xử lý theo cách quy định hoặc trả về giá trị mã ENOSYS cố định cho biết chức năng này không được triển khai.

Lưu ý rằng bộ tài liệu POSIX đã thay đổi trong nhiều năm. Nhưng các nhà phát triển phiên bản mới luôn cố gắng duy trì tính liên tục với các phiên bản trước nhiều nhất có thể. Một cái gì đó mới có thể xuất hiện trong các phiên bản gần đây hơn. Ví dụ, tài liệu năm 2004 kết hợp bốn phần [ 50 ]:

  • Tập Định nghĩa cơ sở (XBD) – định nghĩa các thuật ngữ, khái niệm và giao diện chung cho tất cả các tập của tiêu chuẩn này;
  • Khối lượng giao diện hệ thống (XSH) – giao diện cấp hệ thống và ràng buộc của chúng với ngôn ngữ C, mô tả các giao diện bắt buộc giữa các chương trình ứng dụng và hệ điều hành, đặc biệt – thông số kỹ thuật cuộc gọi hệ thống;
  • Khối lượng Shell và Tiện ích (XCU) – định nghĩa về giao diện trình thông dịch lệnh tiêu chuẩn (còn gọi là shell POSIX), cũng như chức năng cơ bản của các tiện ích Unix;
  • Khối lượng cơ sở lý luận (Thông tin) (XRAT) – bổ sung, bao gồm cả thông tin lịch sử về tiêu chuẩn.

Giống như phiên bản đầu tiên, phần chính của tài liệu mô tả các nhóm dịch vụ được cung cấp. Mỗi phần tử được mô tả ở đó trong các đoạn sau: TÊN (Tên), SINOPSIS (Cú pháp), DISCRIPTION (Mô tả), GIÁ TRỊ TRẢ LẠI (Giá trị trả về), LỖI (Lỗi) và cuối cùng là VÍ DỤ (Ví dụ).

Các phiên bản hiện đại của tiêu chuẩn xác định các yêu cầu cho cả hệ điều hành và chương trình ứng dụng. Hãy đưa ra một ví dụ [ 51 ].

Hàm readdir() phải trả về một con trỏ tới cấu trúc tương ứng với thành phần thư mục tiếp theo. Việc các thành phần thư mục có tên "dot" và "dot-to-dot" có được trả về hay không không được tiêu chuẩn chỉ định. Trong ví dụ này, bốn kết quả có thể xảy ra và yêu cầu về chương trình ứng dụng là nó phải được thiết kế cho bất kỳ ai trong số họ.

Và để kết luận, chúng tôi trình bày một đoạn trích trong quá trình giảng dạy của Sukhomlinov (“GIỚI THIỆU VỀ PHÂN TÍCH CÔNG NGHỆ THÔNG TIN”, Sukhomlinov V.A. Phần V. Phương pháp và hệ thống tiêu chuẩn POSIX OSE), dành riêng cho phạm vi áp dụng của các tiêu chuẩn [ 52 ]:

"Phạm vi áp dụng các tiêu chuẩn POSIX OSE (Môi trường hệ thống mở) là cung cấp các khả năng sau (còn gọi là thuộc tính mở) cho các hệ thông thông tin:

  • Tính di động của ứng dụng ở cấp mã nguồn, tức là cung cấp khả năng chuyển các chương trình và dữ liệu được trình bày dưới dạng mã nguồn của ngôn ngữ lập trình từ nền tảng này sang nền tảng khác.
  • Khả năng tương tác của hệ thống, tức là hỗ trợ kết nối giữa các hệ thống.
  • Khả năng di chuyển của người dùng, tức là cung cấp khả năng cho người dùng làm việc trên các nền tảng khác nhau mà không cần đào tạo lại.
  • Khả năng thích ứng với các tiêu chuẩn mới (Accommodation of Standards) liên quan đến việc đạt được các mục tiêu của hệ thống mở.
  • Khả năng thích ứng với công nghệ thông tin mới (Accommodation of new System Technology) dựa trên tính phổ biến của cấu trúc phân loại dịch vụ và tính độc lập của mô hình với các cơ chế thực hiện.
  • Khả năng mở rộng của nền tảng ứng dụng (Application Platform Scalability), phản ánh khả năng chuyển giao và tái sử dụng phần mềm ứng dụng liên quan đến các loại và cấu hình khác nhau của nền tảng ứng dụng.
  • Khả năng mở rộng của hệ thống phân tán (Distributed System Scalability), phản ánh khả năng hoạt động của phần mềm ứng dụng bất kể sự phát triển của cấu trúc liên kết và tài nguyên của hệ thống phân tán.
  • Minh bạch thực hiện, tức là ẩn các tính năng triển khai của chúng với người dùng đằng sau giao diện hệ thống.
  • Thông số kỹ thuật có hệ thống và chính xác về các yêu cầu chức năng của người dùng (Yêu cầu chức năng của người dùng), đảm bảo tính đầy đủ và rõ ràng trong việc xác định nhu cầu của người dùng, bao gồm cả việc xác định thành phần của các tiêu chuẩn áp dụng."

Điều này cho phép bạn giải quyết các vấn đề sau:

  • tích hợp hệ thống thông tin từ các thành phần từ các nhà sản xuất khác nhau;
  • hiệu quả triển khai và phát triển nhờ tính chính xác của các thông số kỹ thuật và tuân thủ các giải pháp tiêu chuẩn phản ánh trình độ khoa học kỹ thuật tiên tiến;
  • hiệu quả chuyển giao phần mềm ứng dụng, nhờ sử dụng các giao diện được tiêu chuẩn hóa và tính minh bạch của cơ chế triển khai các dịch vụ hệ thống.

Các tiêu chuẩn cũng chính thức xác định các khái niệm quan trọng sau đây của hệ điều hành: người dùng; tài liệu; quá trình; phần cuối; chủ nhà; nút mạng; thời gian; môi trường ngôn ngữ và văn hóa. Việc xây dựng định nghĩa như vậy không được đưa ra ở đó, nhưng các thao tác áp dụng cho chúng và các thuộc tính vốn có trong chúng sẽ được giới thiệu.

Tổng cộng có hơn ba chục thành phần trong danh sách tiêu chuẩn POSIX. Tên của họ theo truyền thống bắt đầu bằng chữ cái "P", theo sau là một số có bốn chữ số với các ký hiệu bổ sung.

Ngoài ra còn có tên nhóm cho các tiêu chuẩn POSIX1, POSIX2, v.v. Ví dụ: POSIX1 được liên kết với các tiêu chuẩn cho giao diện hệ điều hành cơ bản (P1003.1x, trong đó x trống hoặc các ký tự từ a đến g; do đó, có 7 tài liệu trong nhóm này) và POSIX3 liên quan đến các phương pháp thử nghiệm (hai tài liệu - P2003 và P2003n ).

Mỗi máy tính có ngôn ngữ lập trình riêng - ngôn ngữ lệnh hoặc ngôn ngữ máy - và chỉ có thể thực thi các chương trình được viết bằng ngôn ngữ này. Về nguyên tắc, bất kỳ thuật toán nào cũng có thể được mô tả bằng ngôn ngữ máy, nhưng chi phí lập trình sẽ cực kỳ cao. Điều này là do ngôn ngữ máy chỉ cho phép bạn mô tả và xử lý các cấu trúc dữ liệu nguyên thủy - bit, byte, từ. Lập trình bằng mã máy đòi hỏi quá nhiều chi tiết về chương trình và chỉ những lập trình viên có kiến ​​thức tốt về cấu trúc và chức năng của máy tính mới có thể tiếp cận được. Các ngôn ngữ cấp cao (Fortran, PL/1, Pascal, C, Ada, v.v.) với các cấu trúc dữ liệu và phương tiện xử lý được phát triển không phụ thuộc vào ngôn ngữ của một máy tính cụ thể đã giúp khắc phục khó khăn này.

Ngôn ngữ thuật toán cấp cao cho phép lập trình viên mô tả khá đơn giản và thuận tiện các thuật toán để giải quyết nhiều vấn đề bài toán ứng dụng. Mô tả này được gọi là chương trình gốc và ngôn ngữ cấp cao là ngôn ngữ đầu vào.

Bộ xử lý ngôn ngữ là một chương trình ngôn ngữ máy cho phép máy tính hiểu và thực thi các chương trình bằng ngôn ngữ đầu vào. Có hai loại bộ xử lý ngôn ngữ chính: trình thông dịch và trình dịch.

Thông dịch viên là một chương trình chấp nhận một chương trình bằng ngôn ngữ đầu vào làm đầu vào và khi các cấu trúc ngôn ngữ đầu vào được nhận dạng, sẽ triển khai chúng, tạo ra kết quả đầu ra của các phép tính do chương trình nguồn quy định.

Người phiên dịch là một chương trình nhận một chương trình gốc làm đầu vào và tạo ra một chương trình ở đầu ra có chức năng tương đương với chương trình gốc, được gọi là sự vật. Một chương trình đối tượng được viết bằng ngôn ngữ đối tượng. Trong một trường hợp cụ thể, ngôn ngữ máy có thể đóng vai trò là ngôn ngữ đối tượng và trong trường hợp này, chương trình thu được ở đầu ra của trình dịch có thể được thực thi ngay lập tức trên máy tính (thông dịch). Trong trường hợp này, máy tính là trình thông dịch của chương trình đối tượng trong mã máy. Nói chung, ngôn ngữ đối tượng không nhất thiết phải là máy hoặc thứ gì đó gần với nó (mã tự động). Một số ngôn ngữ đối tượng có thể đóng vai trò ngôn ngữ Trung gian– một ngôn ngữ nằm giữa ngôn ngữ đầu vào và ngôn ngữ máy.

Nếu một ngôn ngữ trung gian được sử dụng làm ngôn ngữ đối tượng thì có thể có hai tùy chọn để xây dựng trình dịch.

Tùy chọn đầu tiên là đối với ngôn ngữ trung gian, có (hoặc đang được phát triển) một trình dịch khác từ ngôn ngữ trung gian sang ngôn ngữ máy và nó được sử dụng làm khối cuối cùng của trình dịch được thiết kế.

Tùy chọn thứ hai để xây dựng trình dịch sử dụng ngôn ngữ trung gian là xây dựng trình thông dịch cho các lệnh của ngôn ngữ trung gian và sử dụng nó làm khối cuối cùng của trình dịch. Ưu điểm của trình thông dịch được thể hiện ở việc gỡ lỗi và dịch tương tác, đảm bảo rằng người dùng có thể làm việc ở chế độ tương tác, cho đến khi thực hiện các thay đổi đối với chương trình mà không cần dịch lại hoàn toàn.

Trình thông dịch cũng được sử dụng trong việc mô phỏng chương trình - thực thi các chương trình được biên dịch cho máy (đối tượng) khác trên máy công nghệ. Tùy chọn này, đặc biệt, được sử dụng khi gỡ lỗi trên một chương trình máy tính có mục đích chung sẽ được thực thi trên một máy tính chuyên dụng.

Một trình dịch sử dụng ngôn ngữ gần với ngôn ngữ máy (mã tự động hoặc trình biên dịch mã) làm ngôn ngữ đầu vào thường được gọi là người lắp ráp. Người dịch ngôn ngữ cấp cao được gọi là trình biên dịch.

Những tiến bộ đáng kể đã được thực hiện trong việc phát triển trình biên dịch trong những năm gần đây. Các trình biên dịch đầu tiên sử dụng cái gọi là phương pháp phát sóng trực tiếp- Đây chủ yếu là các phương pháp heuristic, trong đó, dựa trên ý tưởng chungĐối với mỗi cấu trúc ngôn ngữ, thuật toán dịch riêng của nó sang máy tương đương đã được phát triển. Những phương pháp này chậm và không có cấu trúc.

Phương pháp thiết kế các trình biên dịch hiện đại dựa trên phương pháp điều khiển cú pháp thành phần xử lý ngôn ngữ. Thành phần theo nghĩa là quá trình chuyển đổi một chương trình nguồn thành một chương trình đối tượng được thực hiện bằng cách kết hợp các ánh xạ độc lập về chức năng với các cấu trúc dữ liệu đầu vào và đầu ra được xác định rõ ràng. Các ánh xạ này được xây dựng từ việc coi chương trình nguồn là sự kết hợp của các khía cạnh (cấp độ) chính của mô tả ngôn ngữ đầu vào: từ vựng, cú pháp, ngữ nghĩa và ngữ dụng, đồng thời xác định các khía cạnh này từ chương trình nguồn trong quá trình biên dịch. Chúng ta hãy xem xét những khía cạnh này để có được một mô hình trình biên dịch đơn giản hóa.

Cơ sở của bất kỳ yếu tố tự nhiên hoặc ngôn ngữ nhân tạobảng chữ cái– một tập hợp các ký tự cơ bản được phép trong ngôn ngữ (chữ cái, số và ký tự dịch vụ). Các dấu hiệu có thể được kết hợp thành từ– các cấu trúc cơ bản của ngôn ngữ, được coi trong văn bản (chương trình) là những ký hiệu không thể chia cắt, có một ý nghĩa nhất định.


Một từ cũng có thể là một ký tự đơn. Ví dụ, trong ngôn ngữ Pascal, các từ là định danh, từ khóa, hằng số và dấu phân cách, đặc biệt là số học và các phép toán logic, dấu ngoặc đơn, dấu phẩy và các ký hiệu khác. Từ vựng của một ngôn ngữ, cùng với sự mô tả cách chúng được thể hiện, tạo nên từ vựng ngôn ngữ.

Các từ trong một ngôn ngữ được kết hợp thành các cấu trúc phức tạp hơn - câu. Trong các ngôn ngữ lập trình, câu đơn giản nhất là toán tử. Câu được xây dựng từ các từ và các câu đơn giản hơn theo quy tắc cú pháp. Cú pháp ngôn ngữ là sự mô tả các câu đúng. Mô tả ý nghĩa của câu, tức là. nghĩa của từ và các kết nối bên trong của chúng, là ngữ nghĩa ngôn ngữ. Ngoài ra, chúng tôi lưu ý rằng một chương trình cụ thể có một số tác động đến người dịch - chủ nghĩa thực dụng. Kết hợp với nhau, cú pháp, ngữ nghĩa và tính thực dụng của hình thức ngôn ngữ ký hiệu học ngôn ngữ.

Nói chung, dịch một chương trình từ ngôn ngữ này sang ngôn ngữ khác bao gồm việc thay đổi bảng chữ cái, từ vựng và cú pháp của ngôn ngữ chương trình trong khi vẫn duy trì ngữ nghĩa của nó. Quá trình dịch một chương trình nguồn thành một chương trình đối tượng thường được chia thành nhiều quy trình con độc lập (các giai đoạn dịch), được thực hiện bởi các khối dịch tương ứng. Thật thuận tiện khi coi phân tích từ vựng là giai đoạn chính của dịch thuật, phân tích cú pháp, phân tích ngữ nghĩa và

tổng hợp chương trình đối tượng Tuy nhiên, trong nhiều trình biên dịch thực, các giai đoạn này được chia thành nhiều giai đoạn phụ và cũng có thể có các giai đoạn khác (ví dụ: tối ưu hóa mã đối tượng). Trong bộ lễ phục. Hình 1.1 thể hiện mô hình chức năng đơn giản của bộ dịch.

Theo mô hình này, chương trình đầu vào trước tiên được xử lý từ vựng. Mục đích của phân tích từ vựng là dịch chương trình nguồn sang ngôn ngữ bên trong của trình biên dịch, trong đó các từ khóa, mã định danh, nhãn và hằng số được giảm xuống một định dạng duy nhất và được thay thế bằng các mã có điều kiện: số hoặc ký hiệu, được gọi là bộ mô tả. Mỗi bộ mô tả bao gồm hai phần: lớp (loại) của mã thông báo và một con trỏ tới địa chỉ bộ nhớ nơi lưu trữ thông tin về mã thông báo cụ thể. Thông thường thông tin này được tổ chức trong bảng. Đồng thời với việc dịch chương trình nguồn sang ngôn ngữ nội bộ, ở khâu phân tích từ vựng, kiểm soát từ vựng- xác định các từ không được chấp nhận trong chương trình.

Trình phân tích cú pháp lấy đầu ra của bộ phân tích từ vựng và dịch chuỗi hình ảnh mã thông báo sang dạng chương trình trung gian. Một chương trình trung gian về cơ bản là sự biểu diễn cây cú pháp của một chương trình. Cái sau phản ánh cấu trúc của chương trình gốc, tức là. trật tự và kết nối giữa các nhà khai thác của nó. Trong quá trình xây dựng cây cú pháp, kiểm soát cú pháp– Xác định lỗi cú pháp trong chương trình.

Đầu ra thực tế của trình phân tích cú pháp có thể là chuỗi lệnh cần thiết để xây dựng phần mềm trung gian, truy cập các bảng thư mục và đưa ra thông báo chẩn đoán khi được yêu cầu.

Cơm. 1.1. Mô hình chức năng đơn giản hóa của trình dịch

Quá trình tổng hợp một chương trình đối tượng thường bắt đầu bằng việc phân bổ và cấp phát bộ nhớ cho các đối tượng chương trình chính. Sau đó, mỗi câu trong chương trình nguồn sẽ được kiểm tra và tạo ra các câu tương đương về mặt ngữ nghĩa trong ngôn ngữ đối tượng. Thông tin đầu vào ở đây là cây cú pháp của chương trình và các bảng đầu ra của bộ phân tích từ vựng - bảng định danh, bảng hằng số và các bảng khác. Phân tích cây cho phép chúng ta xác định trình tự các lệnh được tạo ra của một chương trình đối tượng và bằng cách sử dụng bảng định danh, chúng ta xác định các loại lệnh hợp lệ cho các giá trị của toán hạng trong các lệnh được tạo ra (ví dụ: lệnh nào cần được tạo: dấu phẩy động hoặc cố định, v.v.).

Việc tạo ra một chương trình đối tượng thực sự thường được bắt đầu bằng phân tích ngữ nghĩa mà bao gồm các loại khác nhau xử lý ngữ nghĩa. Một loại là kiểm tra các quy ước ngữ nghĩa trong một chương trình. Ví dụ về các thỏa thuận như vậy: tính duy nhất trong mô tả của từng mã định danh trong chương trình, định nghĩa của một biến được thực hiện trước khi sử dụng, v.v. Phân tích ngữ nghĩa có thể được thực hiện ở các giai đoạn dịch sau này, chẳng hạn như ở giai đoạn tối ưu hóa chương trình, giai đoạn này cũng có thể được đưa vào trình dịch. Mục tiêu của việc tối ưu hóa là giảm tài nguyên thời gian hoặc tài nguyên RAM cần thiết để thực thi một chương trình đối tượng.

Đây là những khía cạnh chính của quá trình dịch thuật từ các ngôn ngữ cấp cao. Thông tin chi tiết hơn về việc tổ chức các giai đoạn phát sóng khác nhau và các vấn đề liên quan những cách thiết thực mô tả toán học của họ được thảo luận dưới đây.

Người dịch thường chẩn đoán lỗi, biên soạn từ điển định danh, tạo văn bản chương trình để in, v.v.

Phát sóng chương trình- chuyển đổi chương trình được trình bày bằng một trong các ngôn ngữ lập trình sang chương trình bằng ngôn ngữ khác và theo một nghĩa nào đó, tương đương với chương trình đầu tiên.

Ngôn ngữ mà chương trình đầu vào được trình bày được gọi là ngôn ngữ gốc, và chính chương trình - mã nguồn. Ngôn ngữ đầu ra được gọi là ngôn ngữ mục tiêu hoặc mã đối tượng.

Khái niệm dịch thuật không chỉ áp dụng cho các ngôn ngữ lập trình mà còn cho các ngôn ngữ máy tính khác, chẳng hạn như ngôn ngữ đánh dấu, tương tự như HTML và các ngôn ngữ tự nhiên, chẳng hạn như tiếng Anh hoặc tiếng Nga. Tuy nhiên, bài viết này chỉ nói về ngôn ngữ lập trình; đối với ngôn ngữ tự nhiên, hãy xem: Dịch thuật.

Các loại dịch giả

  • Địa chỉ. Một thiết bị chức năng chuyển đổi địa chỉ ảo thành địa chỉ bộ nhớ thực.
  • Hộp thoại. Cung cấp việc sử dụng ngôn ngữ lập trình ở chế độ chia sẻ thời gian.
  • Nhiều lượt. Tạo thành một mô-đun đối tượng qua một số khung nhìn của chương trình nguồn.
  • Mặt sau. Tương tự như detranslator. Xem thêm: trình dịch ngược, trình dịch ngược.
  • Vé đơn. Tạo thành một mô-đun đối tượng trong một lần xem tuần tự của chương trình nguồn.
  • Tối ưu hóa. Thực hiện tối ưu hóa mã trong mô-đun đối tượng được tạo.
  • Định hướng cú pháp (điều khiển cú pháp). Nhận làm đầu vào mô tả cú pháp và ngữ nghĩa của ngôn ngữ và văn bản trong ngôn ngữ được mô tả, được dịch theo mô tả đã cho.
  • Bài kiểm tra. Một tập hợp các macro hợp ngữ cho phép bạn thiết lập các quy trình gỡ lỗi khác nhau trong các chương trình được viết bằng hợp ngữ.

Triển khai

Mục đích của dịch thuật là chuyển đổi văn bản từ ngôn ngữ này sang ngôn ngữ khác để người nhận văn bản có thể hiểu được. Trong trường hợp chương trình dịch, người nhận là thiết bị kỹ thuật (bộ xử lý) hoặc chương trình phiên dịch.

Có một số ví dụ khác trong đó kiến ​​trúc của loạt máy tính được phát triển dựa trên hoặc phụ thuộc rất nhiều vào một số mô hình cấu trúc chương trình. Do đó, dòng GE/Honeywell Multics được dựa trên mô hình ngữ nghĩa thực thi các chương trình viết bằng ngôn ngữ PL/1. Trong Bản mẫu:Không được dịch B5500, B6700 ... B7800 được dựa trên mô hình chương trình thời gian chạy được viết bằng ngôn ngữ ALGOL mở rộng. ...

Bộ xử lý i432, giống như các kiến ​​trúc trước đó, cũng dựa trên mô hình ngữ nghĩa của cấu trúc chương trình. Tuy nhiên, không giống như những người tiền nhiệm của nó, i432 không dựa trên một mô hình ngôn ngữ lập trình cụ thể. Thay vào đó, mục tiêu chính của nhà phát triển là cung cấp hỗ trợ thời gian chạy trực tiếp cho cả dữ liệu trừu tượng(nghĩa là lập trình với các kiểu dữ liệu trừu tượng) và đối với hệ điều hành dành riêng cho miền. …

Ưu điểm của trình biên dịch: chương trình được biên dịch một lần và không cần chuyển đổi bổ sung mỗi lần nó được thực thi. Theo đó, trình biên dịch không cần thiết trên máy mục tiêu mà chương trình được biên dịch. Nhược điểm: Một bước biên dịch riêng biệt làm chậm quá trình viết và gỡ lỗi, đồng thời gây khó khăn cho việc chạy các chương trình nhỏ, đơn giản hoặc chỉ chạy một lần.

Trong trường hợp ngôn ngữ nguồn là hợp ngữ (ngôn ngữ cấp thấp gần với ngôn ngữ máy), thì trình biên dịch của ngôn ngữ đó được gọi là người lắp ráp.

Phương pháp thực hiện ngược lại là khi chương trình được thực thi bằng cách sử dụng thông dịch viên không có phát sóng nào cả. Phần mềm thông dịch mô hình hóa một máy có chu trình tìm nạp-thực thi hoạt động theo hướng dẫn bằng ngôn ngữ cấp cao, thay vì theo hướng dẫn của máy. Mô phỏng phần mềm này tạo ra một máy ảo thực hiện ngôn ngữ. Cách tiếp cận này được gọi là giải thích thuần túy. Phiên dịch thuần túy thường được sử dụng cho các ngôn ngữ có cấu trúc đơn giản (ví dụ: APL hoặc Lisp). Trình thông dịch dòng lệnh xử lý các lệnh trong tập lệnh trong UNIX hoặc trong tệp bó (.bat) trong MS-DOS, cũng thường ở chế độ thông dịch thuần túy.

Ưu điểm của trình thông dịch thuần túy: việc không có các hành động trung gian để dịch giúp đơn giản hóa việc triển khai trình thông dịch và giúp sử dụng thuận tiện hơn, kể cả trong chế độ hộp thoại. Điểm bất lợi là phải có trình thông dịch trên máy đích nơi chương trình sẽ được thực thi. Và đặc tính của một trình thông dịch thuần túy, đó là các lỗi trong chương trình thông dịch chỉ được phát hiện khi cố gắng thực hiện một lệnh (hoặc dòng) có lỗi, có thể được coi là cả nhược điểm và lợi thế.

Có sự thỏa hiệp giữa biên dịch và giải thích thuần túy trong việc triển khai ngôn ngữ lập trình, khi trình thông dịch, trước khi thực hiện chương trình, dịch nó sang ngôn ngữ trung gian (ví dụ: sang mã byte hoặc mã p), thuận tiện hơn cho việc giải thích (nghĩa là, chúng ta đang nói về một trình thông dịch có trình dịch tích hợp) . Phương pháp này được gọi là thực hiện hỗn hợp. Một ví dụ về triển khai ngôn ngữ hỗn hợp là Perl. Cách tiếp cận này kết hợp cả ưu điểm của trình biên dịch và trình thông dịch (tốc độ thực thi cao hơn và dễ sử dụng) và nhược điểm (cần có thêm tài nguyên để dịch và lưu trữ chương trình bằng ngôn ngữ trung gian; phải cung cấp trình thông dịch để thực thi chương trình trên đích. máy móc). Ngoài ra, như trong trường hợp của một trình biên dịch, việc triển khai hỗn hợp yêu cầu mã nguồn không có lỗi (từ vựng, cú pháp và ngữ nghĩa) trước khi thực thi.

Với sự gia tăng tài nguyên máy tính và sự mở rộng của các mạng không đồng nhất (bao gồm cả Internet), kết nối các máy tính thuộc nhiều loại và kiến ​​trúc khác nhau, loại mới thông dịch, trong đó mã nguồn (hoặc mã trung gian) được biên dịch thành mã máy trực tiếp trong thời gian chạy, “nhanh chóng”. Các phần mã đã được biên dịch sẽ được lưu vào bộ nhớ đệm để khi được truy cập lại, chúng sẽ ngay lập tức nhận được quyền kiểm soát mà không cần biên dịch lại. Cách tiếp cận này được gọi là biên soạn năng động.

Ưu điểm của biên dịch động là tốc độ diễn giải chương trình tương đương với tốc độ thực thi chương trình trong các ngôn ngữ biên dịch thông thường, trong khi bản thân chương trình được lưu trữ và phân phối dưới một dạng duy nhất, độc lập với nền tảng đích. Nhược điểm là độ phức tạp triển khai cao hơn và yêu cầu tài nguyên lớn hơn so với trường hợp trình biên dịch đơn giản hoặc trình thông dịch thuần túy.

Phương pháp này hoạt động tốt cho

Gửi công việc tốt của bạn trong cơ sở kiến ​​thức rất đơn giản. Sử dụng mẫu dưới đây

Các sinh viên, nghiên cứu sinh, các nhà khoa học trẻ sử dụng nền tảng kiến ​​thức trong học tập và công việc sẽ rất biết ơn các bạn.

Đăng trên http://www.allbest.ru

Giới thiệu

1.1 Phân tích từ trên xuống

1.2 Phân tích từ dưới lên

1.2.1 LR(k) - ngữ pháp

1.2.1.1 LR(0) - ngữ pháp

1.2.2 LALR(1) - ngữ pháp

2. Phát triển dịch giả

2.1 Phân tích yêu cầu

2.2 Thiết kế

2.2.1 Thiết kế máy phân tích từ vựng

2.2.4 Triển khai phần mềm của trình phân tích cú pháp

2.3 Mã hóa

2.4 Kiểm tra

Phần kết luận

Danh sách các nguồn được sử dụng

Phụ lục A. Danh sách văn bản chương trình dịch

Phụ lục B. Kết quả thử nghiệm

Phụ lục B. Sơ đồ chương trình dịch

Giới thiệu

Đã qua lâu rồi cái thời trước khi viết một chương trình, bạn phải hiểu và ghi nhớ hàng tá lệnh máy. Một lập trình viên hiện đại hình thành nhiệm vụ của mình bằng ngôn ngữ lập trình cấp cao và chỉ sử dụng hợp ngữ trong những trường hợp đặc biệt. Như đã biết, các ngôn ngữ thuật toán chỉ có sẵn cho lập trình viên sau khi tạo ra các trình dịch từ các ngôn ngữ này.

Các ngôn ngữ lập trình khá khác nhau về mục đích, cấu trúc, độ phức tạp về ngữ nghĩa và phương pháp triển khai. Điều này áp đặt các tính năng cụ thể của riêng nó vào sự phát triển của các dịch giả cụ thể.

Ngôn ngữ lập trình là công cụ để giải quyết các vấn đề trong các lĩnh vực chủ đề khác nhau, xác định các đặc điểm cụ thể của tổ chức và sự khác biệt về mục đích của chúng. Các ví dụ bao gồm các ngôn ngữ như Fortran, hướng tới tính toán khoa học và C, dành cho lập trình hệ thống,Prolog, mô tả hiệu quả các vấn đề suy luận, Lisp, được sử dụng để xử lý danh sách đệ quy. Những ví dụ này có thể được tiếp tục. Mỗi lĩnh vực chủ đề đặt ra những yêu cầu riêng về cách tổ chức ngôn ngữ. Vì vậy, có thể nhận thấy sự đa dạng về hình thức biểu diễn toán tử và biểu thức, sự khác biệt về tập hợp các phép toán cơ bản, sự giảm hiệu quả lập trình khi giải các bài toán không liên quan đến lĩnh vực chủ đề. Sự khác biệt về ngôn ngữ cũng được phản ánh trong cấu trúc của người dịch. Lisp và Prolog thường được thực thi ở chế độ diễn giải do chúng sử dụng việc tạo các kiểu dữ liệu động trong quá trình tính toán. Trình dịch Fortran có đặc điểm là tối ưu hóa mạnh mẽ mã máy kết quả, điều này có thể thực hiện được nhờ ngữ nghĩa tương đối đơn giản của cấu trúc ngôn ngữ - đặc biệt là do không có cơ chế đặt tên biến thay thế thông qua con trỏ hoặc tham chiếu. Sự hiện diện của con trỏ trong ngôn ngữ C đặt ra những yêu cầu cụ thể cho việc cấp phát bộ nhớ động.

Cấu trúc của một ngôn ngữ đặc trưng cho mối quan hệ phân cấp giữa các khái niệm của nó, được mô tả bằng các quy tắc cú pháp. Các ngôn ngữ lập trình có thể khác nhau rất nhiều trong cách tổ chức các khái niệm riêng lẻ và mối quan hệ giữa chúng. Ngôn ngữ lập trình PL/1 cho phép lồng các thủ tục và hàm tùy ý, trong khi ở C tất cả các hàm phải ở mức lồng bên ngoài. Ngôn ngữ C++ cho phép khai báo các biến tại bất kỳ điểm nào trong chương trình trước khi sử dụng lần đầu, trong khi trong Pascal, các biến phải được xác định trong một vùng khai báo đặc biệt. Đi xa hơn nữa là PL/1, cho phép khai báo một biến sau khi nó được sử dụng. Hoặc bạn có thể bỏ qua toàn bộ mô tả và sử dụng các quy tắc mặc định. Tùy thuộc vào quyết định được đưa ra, người dịch có thể phân tích chương trình theo một hoặc nhiều lượt, điều này ảnh hưởng đến tốc độ dịch.

Ngữ nghĩa của các ngôn ngữ lập trình rất khác nhau. Chúng khác nhau không chỉ ở các tính năng triển khai của các hoạt động riêng lẻ mà còn ở các mô hình lập trình, những yếu tố quyết định sự khác biệt cơ bản trong phương pháp phát triển chương trình. Các chi tiết cụ thể của việc thực hiện các hoạt động có thể liên quan đến cả cấu trúc của dữ liệu đang được xử lý và các quy tắc xử lý cùng loại dữ liệu. Các ngôn ngữ như PL/1 và APL hỗ trợ các phép toán ma trận và vectơ. Hầu hết các ngôn ngữ hoạt động chủ yếu với các đại lượng vô hướng, cung cấp các thủ tục và hàm do các lập trình viên viết để xử lý mảng. Nhưng ngay cả khi thực hiện thao tác cộng hai số nguyên, các ngôn ngữ như C và Pascal vẫn có thể hoạt động khác.

Cùng với truyền thống lập trình thủ tục, còn được gọi là mệnh lệnh, có những mô hình như lập trình chức năng lập trình logic và lập trình hướng đối tượng. Cấu trúc của các khái niệm và đối tượng của ngôn ngữ phụ thuộc rất nhiều vào mô hình đã chọn, điều này cũng ảnh hưởng đến việc triển khai của người dịch.
Ngay cả cùng một ngôn ngữ cũng có thể được thực hiện theo nhiều cách. Điều này là do thực tế là lý thuyết về ngữ pháp hình thức cho phép Các phương pháp khác nhau phân tích các câu giống nhau. Theo đó, người dịch có thể thu được cùng một kết quả (chương trình đối tượng) từ văn bản nguồn gốc theo nhiều cách khác nhau.
Đồng thời, tất cả các ngôn ngữ lập trình đều có một số đặc điểm và thông số chung. Điểm chung này cũng quyết định nguyên tắc tổ chức dịch giả giống nhau cho tất cả các ngôn ngữ.
Ngôn ngữ lập trình được thiết kế để giúp việc lập trình trở nên dễ dàng hơn. Do đó, các toán tử và cấu trúc dữ liệu của chúng mạnh hơn so với các ngôn ngữ máy.
Để tăng tính rõ ràng của chương trình, thay vì mã số, ký hiệu hoặc biểu diễn đồ họa cấu trúc ngôn ngữ thuận tiện hơn cho nhận thức của con người.
Đối với bất kỳ ngôn ngữ nào, nó được xác định:
- nhiều ký hiệu có thể được sử dụng để viết chương trình chính xác (bảng chữ cái), các phần tử cơ bản,
- nhiều chương trình đúng (cú pháp),
- “ý nghĩa” của mọi chương trình đúng (ngữ nghĩa).
Bất kể đặc điểm cụ thể của ngôn ngữ, bất kỳ người dịch nào cũng có thể được coi là bộ chuyển đổi chức năng F, cung cấp ánh xạ duy nhất từ ​​X sang Y, trong đó X là chương trình ở ngôn ngữ nguồn, Y là chương trình ở ngôn ngữ đầu ra. Do đó, bản thân quá trình dịch thuật có thể được biểu diễn một cách hình thức khá đơn giản và rõ ràng: Y = F(X).
Về mặt hình thức, mỗi đúng chương trình X là một chuỗi ký tự từ bảng chữ cái A nào đó, được chuyển đổi thành chuỗi Y tương ứng, bao gồm các ký tự từ bảng chữ cái B.
Một ngôn ngữ lập trình, giống như bất kỳ hệ thống phức tạp nào, được xác định thông qua hệ thống phân cấp các khái niệm xác định mối quan hệ giữa các phần tử của nó. Các khái niệm này được kết nối với nhau theo các quy tắc cú pháp. Mỗi chương trình được xây dựng theo các quy tắc này đều có cấu trúc phân cấp tương ứng.
Về vấn đề này, các đặc điểm chung sau đây có thể được phân biệt bổ sung cho tất cả các ngôn ngữ và chương trình của chúng: mỗi ngôn ngữ phải chứa các quy tắc cho phép tạo chương trình tương ứng với ngôn ngữ này hoặc nhận ra sự tương ứng giữa các chương trình viết và một ngôn ngữ nhất định.

Khác tính năng đặc trưng của tất cả các ngôn ngữ là ngữ nghĩa của chúng. Nó xác định ý nghĩa của các phép toán ngôn ngữ và tính chính xác của các toán hạng. Các chuỗi có cùng cấu trúc cú pháp trong các ngôn ngữ lập trình khác nhau có thể khác nhau về ngữ nghĩa (ví dụ: được quan sát thấy trong C++, Pascal, Basic). Kiến thức về ngữ nghĩa của một ngôn ngữ cho phép bạn tách nó khỏi cú pháp của nó và sử dụng nó để chuyển đổi sang ngôn ngữ khác (để tạo mã).

Mục đích của khóa học này là phát triển một dịch giả giáo dục từ một ngôn ngữ đơn giản hóa nhất định. ngôn ngữ văn bản cấp độ cao.

1. Phương pháp phân tích ngữ pháp

Chúng ta hãy xem xét các phương pháp phân tích ngữ pháp cơ bản.

1.1 Phân tích từ trên xuống

Khi phân tích từ trên xuống dưới, các đạo trình trung gian di chuyển dọc theo cây theo hướng từ gốc đến lá. Trong trường hợp này, khi xem chuỗi từ trái sang phải, đương nhiên sẽ thu được kết luận thuận tay trái. Trong phân tích cú pháp xác định, vấn đề sẽ là áp dụng quy tắc nào để giải quyết kết thúc ngoài cùng bên trái.

1.1.1 LL(k) - ngôn ngữ và ngữ pháp

Xét cây suy luận trong quá trình lấy đầu ra bên trái của chuỗi. Chuỗi trung gian trong quá trình suy luận bao gồm một chuỗi các thiết bị đầu cuối w, phần không phải đầu cuối A ngoài cùng bên trái, phần x được suy ra dưới đây:

-S--

/ \

/ -Cây rìu-\

/ | \

-w---u---

Hình 1

Để tiếp tục phân tích cú pháp, cần thay thế ký tự A không kết thúc theo một trong các quy tắc có dạng A:y. Nếu bạn muốn phân tích cú pháp mang tính xác định (không trả về), quy tắc này cần phải được chọn theo cách đặc biệt. Một ngữ pháp được cho là có thuộc tính LL(k) nếu, để chọn một quy tắc, chỉ cần xem xét wAx và k ký tự đầu tiên của chuỗi u chưa được kiểm tra là đủ. Chữ cái đầu tiên L (Trái) dùng để xem chuỗi đầu vào từ trái sang phải, chữ thứ hai dùng để chỉ đầu ra bên trái đang được sử dụng.

Hãy xác định hai bộ chuỗi:

a) FIRST(x) là tập hợp các chuỗi đầu cuối dẫn xuất từ ​​x, được rút ngắn còn k ký tự.

b) FOLLOW(A) - một tập hợp các chuỗi đầu cuối được rút ngắn còn k ký tự, có thể ngay sau A trong chuỗi đầu ra.

Một ngữ pháp có thuộc tính LL(k) nếu, từ sự tồn tại của hai chuỗi suy luận trái:

S:: wAx: wzx:: wu

S:: wAx: wtx:: wv

từ điều kiện FIRST(u)=FIRST(v) nó tuân theo z=t.

Trong trường hợp k=1, để chọn quy tắc cho A, chỉ cần biết ký tự đầu cuối A và a - ký tự đầu tiên của chuỗi u là đủ:

- quy tắc A:x nên được chọn nếu a được bao gồm trong FIRST(x),

- quy tắc A:e nên được chọn nếu a nằm trong FOLLOW(A).

Thuộc tính LL(k) áp đặt những hạn chế khá mạnh về ngữ pháp. Ví dụ: ngữ pháp LL(2) S: aS | a không có thuộc tính LL(1) vì ĐẦU TIÊN(aS)= ĐẦU TIÊN(a)=a. TRONG trong trường hợp này bạn có thể giảm giá trị của k bằng cách sử dụng “nhân tố hóa” (lấy hệ số ra khỏi ngoặc):

S: aA

Đáp: S | e

Mọi ngữ pháp LL(k) đều rõ ràng. Văn phạm đệ quy trái không thuộc lớp LL(k) với mọi k. Đôi khi có thể chuyển đổi một ngữ pháp không phải LL(1) thành một ngữ pháp LL(1) tương đương bằng cách loại bỏ đệ quy trái và phân tích nhân tử. Tuy nhiên, vấn đề tồn tại của một ngữ pháp LL(k) tương đương đối với một ngữ pháp không phải LL(k) tùy ý là không thể giải quyết được.

1.1.2 Phương pháp đệ quy gốc

Phương pháp giảm dần đệ quy nhằm vào những trường hợp khi trình biên dịch được lập trình bằng một trong các ngôn ngữ cấp cao, khi cho phép sử dụng các thủ tục đệ quy.

Ý tưởng chính của việc giảm đệ quy là mỗi nonterminal của ngữ pháp có một thủ tục tương ứng nhận dạng bất kỳ chuỗi nào được tạo ra bởi nonterminal này. Các thủ tục này gọi nhau khi được yêu cầu.

Giảm dần đệ quy có thể được sử dụng cho bất kỳ ngữ pháp LL(1) nào. Mỗi phần không kết thúc của ngữ pháp có một quy trình tương ứng, bắt đầu bằng việc chuyển sang nhãn được tính toán và chứa mã tương ứng với từng quy tắc cho phần không kết thúc này. Đối với những ký hiệu đầu vào thuộc về tập lựa chọn của quy tắc này, quá trình chuyển đổi được tính toán sẽ chuyển điều khiển sang mã phù hợp với quy tắc đó. Đối với các ký hiệu đầu vào còn lại, điều khiển được chuyển sang quy trình xử lý lỗi.

Mã của bất kỳ quy tắc nào đều chứa các thao tác cho từng ký tự ở phía bên phải của quy tắc. Các thao tác được sắp xếp theo thứ tự xuất hiện các ký hiệu trong quy tắc. Sau thao tác cuối cùng, mã chứa kết quả trả về từ thủ tục.

Việc sử dụng phương pháp gốc đệ quy trong ngôn ngữ cấp cao giúp việc lập trình và gỡ lỗi trở nên dễ dàng hơn.

1.2 Phân tích từ dưới lên

Hãy xem xét phân tích cú pháp từ dưới lên, trong đó các chân trung gian được di chuyển dọc theo cây về phía gốc. Nếu đọc các ký tự trong chuỗi từ trái qua phải thì cây phân tích sẽ có dạng như sau:

-S--

/ \

/-x-\

/ | \

--w--b--u-

Hình 2

Đầu ra trung gian có dạng xbu, trong đó x là một chuỗi gồm các thiết bị đầu cuối và không phải thiết bị đầu cuối, từ đó phần được xem của chuỗi thiết bị đầu cuối w là đầu ra, bu là phần chưa được xem của chuỗi thiết bị đầu cuối, b là ký hiệu tiếp theo. Để tiếp tục phân tích, bạn có thể thêm ký tự b vào phần được xem của chuỗi (thực hiện cái gọi là “shift”) hoặc chọn ở cuối x một chuỗi z (x=yz) mà một trong các chuỗi đó các quy tắc ngữ pháp B:z có thể được áp dụng cho z và thay thế x thành chuỗi yB (thực hiện cái gọi là “tích chập”):

-S-- -S--

/ \ / \

/-x-b-\ /yB-\

/ | \ / | \

--w--b--u- --w--b--u-

Hình 3 - Sau shift Hình 4 - Sau khi tích chập

Nếu tích chập chỉ được áp dụng cho các ký tự cuối cùng của x thì chúng ta sẽ nhận được kết quả đầu ra đúng của chuỗi. Quá trình phân tích cú pháp này được gọi là LR, trong đó ký hiệu L (Trái, trái) ám chỉ việc xem chuỗi từ trái sang phải và R (Phải, phải) ám chỉ kết quả đầu ra.

Trình tự các thao tác dịch chuyển và gấp là rất cần thiết. Do đó, phân tích cú pháp xác định yêu cầu lựa chọn giữa dịch chuyển và tích chập (và các quy tắc tích chập khác nhau) tại mỗi thời điểm.

1.2.1 LR(k) - ngữ pháp

Nếu trong quá trình phân tích cú pháp LR, có thể đưa ra quyết định tất định về dịch chuyển/rút gọn, chỉ xem xét chuỗi x và k ký tự đầu tiên của phần không nhìn thấy của chuỗi đầu vào u (k ký tự này được gọi là chuỗi nâng cao ), ngữ pháp được cho là có thuộc tính LR(k).

-S--

/ \

/-x-\

--w----u--

Hình 5

Sự khác biệt giữa ngữ pháp LL(k) và LR(k) về cây suy luận:

-S-

/ | \

/MỘT\

/ / \ \

-w---v---u-

Hình 6

Trong trường hợp ngữ pháp LL(k), quy tắc áp dụng cho A có thể được xác định duy nhất bởi w và k ký tự đầu tiên của vu, và trong trường hợp ngữ pháp LR(k), bởi w,v và k ký tự đầu tiên nhân vật của bạn. Lý do không chặt chẽ này cho thấy rằng ngôn ngữ LL(k)< LR(k)-языки (при k > 0).

1.2.1.1 LR(0) - ngữ pháp

Đầu tiên chúng ta hãy xem xét các ngữ pháp đơn giản nhất của lớp này - LR(0). Khi phân tích cú pháp một chuỗi bằng ngôn ngữ LR(0), bạn hoàn toàn không phải sử dụng chuỗi nâng cao - việc lựa chọn giữa dịch chuyển và gấp được thực hiện dựa trên chuỗi x. Vì trong quá trình phân tích cú pháp, nó chỉ thay đổi từ đầu bên phải nên nó được gọi là ngăn xếp. Giả sử rằng không có ký hiệu vô dụng nào trong ngữ pháp và ký hiệu ban đầu không xuất hiện ở phía bên phải của quy tắc - khi đó phép tích chập đối với ký hiệu ban đầu báo hiệu việc phân tích cú pháp đã hoàn thành thành công. Hãy thử mô tả tập hợp các chuỗi thiết bị đầu cuối và không thiết bị đầu cuối xuất hiện trên ngăn xếp trong tất cả quá trình phân tích cú pháp LR (nói cách khác, tất cả các suy luận bên phải từ ngữ pháp).

Hãy xác định các tập hợp sau:

L(A:v) - ngữ cảnh bên trái của quy tắc A:v - tập hợp các trạng thái ngăn xếp ngay trước khi v được xếp vào A trong tất cả các phân tích cú pháp LR thành công. Rõ ràng, mọi chuỗi trong L(A:v) đều kết thúc tại v. Nếu đuôi v của tất cả các chuỗi như vậy bị cắt đi thì chúng ta sẽ có được tập hợp các chuỗi xuất hiện ở bên trái của A trong tất cả các suy luận thành công ở bên phải. Chúng ta hãy ký hiệu tập hợp này là L(A) - ngữ cảnh bên trái của ký hiệu không đầu cuối A.

Chúng ta hãy xây dựng một ngữ pháp cho tập L(A). Các kết thúc của ngữ pháp mới sẽ là kết thúc và không kết thúc của ngữ pháp gốc; ,... - giá trị của chúng sẽ là ngữ cảnh bên trái của nonterminals của ngữ pháp gốc. Nếu S là ký hiệu đầu tiên của ngữ pháp gốc thì ngữ pháp ngữ cảnh bên trái sẽ chứa quy tắc : e - ngữ cảnh bên trái S chứa một chuỗi rỗng Đối với mỗi quy tắc của ngữ pháp gốc, ví dụ A: B C d E

và thêm quy tắc vào ngữ pháp mới:

: - L(B) bao gồm L(A)

: B - L(C) bao gồm L(A) B

: B C d - L(E) bao gồm L(A) B C d

Ngữ pháp thu được có dạng đặc biệt (các ngữ pháp như vậy được gọi là tuyến tính trái), do đó, các tập hợp ngữ cảnh bên trái

- thường xuyên. Theo đó, liệu một chuỗi có thuộc ngữ cảnh bên trái của một chuỗi không kết thúc hay không có thể được tính toán theo cách quy nạp bằng cách sử dụng máy trạng thái hữu hạn, quét chuỗi từ trái sang phải. Hãy để chúng tôi mô tả quá trình này một cách xây dựng.

Chúng ta hãy gọi một tình huống LR(0) là một quy tắc ngữ pháp với một vị trí được đánh dấu giữa các ký hiệu ở vế phải của quy tắc. Ví dụ: đối với ngữ pháp S:A; Đ:aAA; A:b tồn tại các tình huống LR(0) sau đây: S:_A; S:A_; Đ:_aAA; Đ:a_AA; Đ:aA_A; Đ:aAA_; Đ:_b; Đ:b_. (vị trí được biểu thị bằng dấu gạch dưới).

Chúng ta sẽ nói rằng chuỗi x phù hợp với tình huống A:b_c nếu x=ab và a thuộc L(A). (Nói cách khác, đầu ra LR có thể được tiếp tục x_... = ab_...:: abc_...:: aA_...:: S_.) Trong các thuật ngữ này, L(A:b) là tập hợp của các chuỗi phù hợp với tình huống A:b_, L(A)

- chuỗi phù hợp với tình huống A:_b, với mọi quy tắc A:b.

Cho V(u) là tập hợp các tình huống phù hợp với u. Hãy chứng minh rằng hàm V có tính quy nạp.

Nếu tập V(u) bao gồm tình huống A:b_cd thì tình huống A:bc_d thuộc về V(uc). (c - thiết bị đầu cuối hoặc không thiết bị đầu cuối; b, d - chuỗi (có thể trống) của thiết bị đầu cuối và không thiết bị đầu cuối). Không có tình huống nào khác có dạng A:b_d, với b không trống trong V(uc). Vẫn còn phải thêm vào các tình huống V(uc) có dạng C:_..., cho mỗi C không phải đầu cuối có ngữ cảnh bên trái chứa uc. Nếu tình huống A:..._C... (C-nonterminal) thuộc tập V(uc), thì uc thuộc L(C) và V(uc) bao gồm các tình huống có dạng C:_... cho tất cả các quy tắc ngữ pháp C-.

V(e) chứa các tình huống S:_... (ký tự bắt đầu bằng S), cũng như các tình huống A:_... nếu ký tự không kết thúc A xảy ra ngay sau _ trong các tình huống đã có trong V(e).

Cuối cùng, chúng ta đã sẵn sàng định nghĩa một ngữ pháp LR(0). Giả sử u là nội dung của ngăn xếp trong quá trình phân tích cú pháp LR và V(u) là tập hợp các tình huống LR(0) phù hợp với u. Nếu V(u) chứa tình huống có dạng A:x_ (chuỗi x của thiết bị đầu cuối và không thiết bị đầu cuối), thì u thuộc về L(A:x) và phép tích chập của x thành A được cho phép. ) chứa tình huống A:..._a.. (a-terminal), thì được phép dịch chuyển. Xung đột dịch chuyển-giảm được cho là tồn tại nếu cả dịch chuyển và tích chập đều được phép cho cùng một chuỗi u. Xung đột giảm tích chập được cho là tồn tại nếu cho phép tích chập theo các quy tắc khác nhau.

Một ngữ pháp được gọi là LR(0) nếu không có xung đột giảm dịch chuyển hoặc giảm gấp đối với tất cả các trạng thái ngăn xếp trong quá trình suy luận LR.

1.2.1.2 LR(k) - ngữ pháp

Chỉ trạng thái của ngăn xếp được sử dụng để quyết định giữa dịch chuyển và gấp trong phân tích cú pháp LR(0). Phân tích cú pháp LR(k) cũng tính đến k ký tự đầu tiên của phần không nhìn thấy được của chuỗi đầu vào (được gọi là chuỗi nâng cao). Để biện minh cho phương pháp, bạn nên cẩn thận lặp lại lý do của đoạn trước, thực hiện các thay đổi đối với các định nghĩa.

Chúng tôi cũng sẽ bao gồm một chuỗi nâng cao trong ngữ cảnh bên trái của các quy tắc. Nếu đầu ra bên phải sử dụng đầu ra wAu: wvu thì cặp wv,FIRSTk(u) thuộc về Lk(A:v) và cặp w,FIRSTk(u) thuộc về Lk(A). Tập hợp các ngữ cảnh bên trái, như trong trường hợp LR(0), có thể được tính bằng cách sử dụng quy nạp trên chuỗi bên trái. Chúng ta hãy gọi một tình huống LR(k) là một cặp: một quy tắc ngữ pháp có vị trí được đánh dấu và một chuỗi nâng cao có độ dài không quá k. Chúng ta sẽ tách quy tắc khỏi chuỗi nâng cao bằng một đường thẳng đứng.

Chúng ta sẽ nói rằng chuỗi x nhất quán với tình huống A:b_c|t nếu có đầu ra LR: x_yz = ab_yz:: abc_z:: aA_z:: S_ và FIRSTk(z) = t. Các quy tắc tính toán quy nạp tập hợp các trạng thái Vk như sau:

Vk(e) chứa các tình huống S:_a|e cho tất cả các quy tắc S:a, trong đó S là ký tự bắt đầu. Với mỗi tình huống A:_Ba|u từ Vk(e), mỗi quy tắc B:b và chuỗi x thuộc FIRSTk(au), cần thêm tình huống B:_b|x vào Vk(e).

Nếu Vк(w) bao gồm tình huống A:b_cd|u thì tình huống A:bc_d|u sẽ thuộc về Vk(wc). Với mỗi tình huống A:b_Cd|u từ Vk(wc), mỗi quy tắc C:f và chuỗi x thuộc FIRSTk(du) cần thêm tình huống C:_f|x vào Vk(wc).

Chúng tôi sử dụng các tập hợp trạng thái LR(k) được xây dựng để giải quyết vấn đề dịch chuyển. Gọi u là nội dung của ngăn xếp và x là chuỗi trên. Rõ ràng, tích chập theo quy tắc A:b có thể được thực hiện nếu Vk(u) chứa tình huống A:b_|x. Việc quyết định xem có cho phép thay đổi hay không đòi hỏi phải cẩn thận nếu ngữ pháp có chứa các quy tắc điện tử. Trong trường hợp A:b_c|t (c không trống), có thể dịch chuyển nếu c bắt đầu từ một thiết bị đầu cuối và x thuộc FIRSTk(ct). Nói một cách không chính thức, bạn có thể đẩy biểu tượng ngoài cùng bên trái của vế phải của quy tắc vào ngăn xếp, chuẩn bị phép tích chập tiếp theo. Nếu c bắt đầu bằng một số không kết thúc (tình huống trông giống như A:b_Cd|t), thì việc đẩy một ký hiệu lên ngăn xếp để chuẩn bị tích chập thành C chỉ có thể thực hiện được nếu C không tạo ra một chuỗi rỗng. Ví dụ: ở trạng thái V(e)= S:_A|e; A:_AaAb|e,a, A:_|e,a không có sự thay đổi nào được phép, bởi vì Khi lấy chuỗi đầu cuối từ A, tại một số bước cần phải áp dụng quy tắc A:e cho đầu cuối A nằm ở đầu bên trái của chuỗi.

Chúng ta hãy định nghĩa tập EFFk(x), bao gồm tất cả các phần tử của tập FIRSTk(x), trong quá trình đạo hàm mà phần tử không kết thúc ở đầu bên trái của x (nếu có) không được thay thế bằng một chuỗi rỗng. Trong các thuật ngữ này, một phép dịch chuyển được cho phép nếu trong tập Vk(u) có tình huống A:b_c|t, c không trống và x thuộc EFFk(ct).

Một ngữ pháp được gọi là ngữ pháp LR(k) nếu không có trạng thái LR(k) nào chứa hai tình huống A:b_|u và B:c_d|v sao cho u thuộc về EFFk(dv). Một cặp như vậy tương ứng với xung đột giảm lần lượt nếu d trống và xung đột dịch chuyển lần đầu nếu d không trống.

Trong thực tế, ngữ pháp LR(k) không được sử dụng cho k>1. Có hai lý do cho việc này. Thứ nhất: rất con số lớn trạng thái LR(k). Thứ hai: đối với bất kỳ ngôn ngữ nào được xác định bởi ngữ pháp LR(k), đều có ngữ pháp LR(1); Hơn nữa, đối với bất kỳ ngôn ngữ KS xác định nào cũng có ngữ pháp LR(1).

Số lượng trạng thái LR(1) cho các ngữ pháp thực tế thú vị cũng khá lớn. Những ngữ pháp như vậy hiếm khi có thuộc tính LR(0). Trong thực tế, phương pháp trung gian giữa LR(0) và LR(1), được gọi là LALR(1), thường được sử dụng hơn.

1.2.2 LALR(1) - ngữ pháp

Hai phương pháp này đều dựa trên cùng một ý tưởng. Chúng ta hãy xây dựng một tập hợp các trạng thái LR(0) chính tắc của ngữ pháp. Nếu bộ này không chứa xung đột thì có thể sử dụng trình phân tích cú pháp LR(0). Mặt khác, chúng tôi sẽ cố gắng giải quyết các xung đột đã phát sinh bằng cách xem xét chuỗi nâng cao một ký tự. Nói cách khác, hãy thử xây dựng một trình phân tích cú pháp LR(1) với nhiều trạng thái LR(0).

Phương pháp LALR(1) (Nhìn về phía trước) như sau. Chúng ta hãy giới thiệu một quan hệ tương đương trên tập hợp các tình huống LR(1): chúng ta sẽ xem xét hai tình huống tương đương nhau nếu chúng chỉ khác nhau ở chuỗi dẫn đầu. Ví dụ: các tình huống A:Aa_Ab|e và A:Aa_Ab|a là tương đương. Hãy xây dựng một tập hợp chuẩn các trạng thái LR(1) và kết hợp các trạng thái bao gồm một tập hợp các tình huống tương đương.

Nếu tập hợp các trạng thái kết quả không chứa xung đột LR(1) và do đó cho phép xây dựng trình phân tích cú pháp LR(1), thì ngữ pháp được cho là có thuộc tính LALR(1).

2. Phát triển dịch giả

2.1 Phân tích yêu cầu

Trong khóa học này, cần phát triển một dịch giả giáo dục dưới dạng một phiên dịch viên từ một ngôn ngữ được xác định bởi ngữ pháp chính thức tương ứng. Có bốn giai đoạn chính trong việc phát triển một phiên dịch viên:

Thiết kế máy phân tích từ vựng;

Thiết kế máy bán hàng tự động;

Triển khai phần mềm trình phân tích cú pháp;

Phát triển mô-đun giải thích.

Việc phát triển sẽ được thực hiện bằng hệ điều hành Windows XP trên thiết bị cá nhân máy tính IBM PC có bộ xử lý Intel Pentium IV.

Dựa trên xu hướng phát triển phần mềm, ngôn ngữ lập trình C# trong môi trường Visual Studio 2010 đã được chọn để triển khai công cụ dịch thuật giáo dục.

2.2 Thiết kế

2.1.1 Thiết kế máy phân tích từ vựng

từ vựng phân tích bao gồm việc quét chương trình (nguồn) đã dịch và nhận ra các từ vựng tạo nên các câu của văn bản nguồn. Đặc biệt, các mã thông báo bao gồm từ khóa, dấu hiệu hoạt động, mã định danh, hằng số, ký tự đặc biệt, v.v.

Kết quả công việc của máy phân tích từ vựng (máy quét) là một chuỗi các mã thông báo, với mỗi mã thông báo thường được biểu thị bằng một số mã có độ dài cố định (ví dụ: một số nguyên), cũng như tạo ra các thông báo về lỗi cú pháp (từ vựng) , nếu có. Ví dụ: nếu mã thông báo là một từ khóa thì mã của nó sẽ cung cấp tất cả thông tin cần thiết. Ví dụ, trong trường hợp một mã định danh, cần phải có thêm tên của mã định danh được công nhận, tên này thường được ghi trong bảng các mã định danh, được sắp xếp theo quy tắc bằng cách sử dụng danh sách. Một bảng tương tự là cần thiết cho các hằng số.

Một từ vị có thể được mô tả bằng hai đặc điểm chính. Một trong số đó là từ vựng thuộc về một lớp nhất định (biến, hằng, phép toán, v.v.). Thuộc tính thứ hai xác định một phần tử cụ thể của lớp này.

Hình thức cụ thể của bảng ký hiệu (cấu trúc dữ liệu) không quan trọng đối với từ vựng hoặc trình phân tích cú pháp. Cả hai đều chỉ cần cung cấp khả năng lấy chỉ mục xác định duy nhất, ví dụ: một biến nhất định và trả về giá trị chỉ mục để bổ sung thông tin về tên biến nhất định trong bảng ký hiệu.

Xem bảng ID thực hiện hai chức năng chính:

a) ghi tên mới vào bảng khi xử lý mô tả biến;

b) tìm kiếm tên đã được ghi trước đó trong bảng.

Điều này giúp có thể xác định được những tình huống sai lầm, chẳng hạn như nhiều mô tả về một biến và sự hiện diện của một biến không được mô tả.

Sự phát triển của máy phân tích từ vựng bao gồm một phần của việc mô hình hóa các automata khác nhau để nhận dạng mã định danh, hằng số, từ dành riêng, v.v. Nếu các mã thông báo thuộc các loại khác nhau bắt đầu bằng cùng một ký tự hoặc cùng một chuỗi ký tự, có thể cần phải kết hợp nhận dạng của chúng.

Bằng cách chạy trình phân tích từ vựng, chúng tôi chia chương trình của mình thành các mã thông báo, sau đó mỗi mã thông báo sẽ vượt qua bước kiểm tra độ dài (một mã thông báo không được dài hơn 11 ký tự). Sau khi hoàn thành thành công giai đoạn này, chúng tôi kiểm tra vị trí chính xác của các mã thông báo (từ khóa var, start, end, for, to, do, end_for). Sau đó, chúng tôi phân tích các từ vựng có thể thay đổi - chúng không được chứa các số trong mô tả và không được lặp lại. Ở giai đoạn cuối, chúng tôi kiểm tra cách viết đúng chính tả của từ vựng (từ khóa, số nhận dạng không xác định). Nếu ít nhất một trong các lần kiểm tra không thành công, bộ phân tích từ vựng sẽ in ra lỗi.

Sơ đồ chương trình phân tích từ vựng được trình bày tại Phụ lục B trong Hình B.1.

2.2.2 Thiết kế máy bán hàng tự động

Hãy xác định ngữ pháp sau:

G: (Vt, Va, I, R),

trong đó Vt là một tập hợp ký tự đầu cuối, Va là tập các ký hiệu không kết thúc, I là trạng thái ban đầu của ngữ pháp, R là tập các quy tắc ngữ pháp.

Đối với ngữ pháp này, chúng tôi xác định bộ ký hiệu đầu cuối và không đầu cuối:

Hãy soạn các quy tắc cho ngữ pháp G của chúng ta và trình bày chúng trong Bảng 1.

Bảng 1 - Quy tắc ngữ pháp

Quy tắc số

Vế trái của quy tắc

Phía bên phải của quy tắc

f ID = EX t EX d LE n;

Tiếp tục bảng 1.

Quy tắc số

Vế trái của quy tắc

Phía bên phải của quy tắc

Các ký hiệu từ vị, cách dịch các từ vị thành mã và danh sách các ký hiệu ngữ pháp được đưa ra tương ứng trong các bảng 2, 3, 4.

Bảng 2 - Ký hiệu các từ vị

Chỉ định mã thông báo

từ khóa “bắt đầu” (bắt đầu mô tả hành động)

từ khóa “end” (kết thúc mô tả hành động)

từ khóa "var" (mô tả biến)

từ khóa "đọc" (toán tử nhập dữ liệu)

từ khóa "ghi" (toán tử xuất dữ liệu)

từ khóa "for" (câu lệnh vòng lặp)

từ khóa "đến"

từ khóa "làm"

từ khóa "end_case" (câu lệnh kết thúc vòng lặp)

loại biến "số nguyên"

phép cộng

phép trừ

phép nhân

ký tự phân cách ://

ký tự phân cách ";"

ký tự phân cách "("

ký tự phân cách ")"

ký tự phân cách ","

Chỉ định mã thông báo

ký tự phân cách "="

Bảng 3 - Dịch từ vựng sang mã

<цифра>

<буква>

Bảng 4 - Danh sách các ký hiệu ngữ pháp

chỉ định

Giải trình

Chương trình

Mô tả tính toán

Mô tả các biến

Danh sách các biến

Nhà điều hành

Phân công

Sự biểu lộ

Biểu hiện phụ

Hoạt động nhị phân

Hoạt động đơn nhất

Danh sách nhiệm vụ

Mã định danh

Không thay đổi

Hãy xây dựng một công cụ nhận dạng từ dưới lên xác định.

Hãy xem xét các mối quan hệ sau để xây dựng một bộ nhận dạng từ dưới lên xác định:

a) Nếu có một ký hiệu thuộc nhóm B sao cho một quy tắc ngữ pháp nào đó bao gồm chuỗi AB và có ký hiệu xFIRST"(B), thì chúng ta sẽ giả sử rằng các quan hệ x SAU A được xác định giữa các ký hiệu x và A

b) Nếu trong một ngữ pháp cho trước có quy tắc B -> bAb A, BV a, b thì quan hệ A COVER x được xác định giữa A và x.

Tất cả ngữ pháp của chúng tôi vẫn giữ nguyên, đó là:

G: (Vt, Va, I, R),

và các quy tắc ngữ pháp G được cho trong Bảng 5.

Bảng 5 - Quy tắc ngữ pháp

Quy tắc số

Vế trái của quy tắc

Phía bên phải của quy tắc

f ID = EX t EX d LE n;?

Tiếp tục bảng 5.

Quy tắc số

Vế trái của quy tắc

Phía bên phải của quy tắc

Ở đâu? - điểm đánh dấu cho sự kết thúc của chuỗi.

Hãy xác định một số trường hợp:

a) ID bao gồm nhiều chữ cái trong bảng chữ cái Latinh, nghĩa là chúng ta sẽ giả sử rằng u = ( a, b, c, d, e, f,g, h, i,j,k, l,m, n , o, p, q, r, s, t, u, v, w, x, y, z)

b) Hằng số CO gồm các số, tức là ta giả sử k = (0,1,2,3,4,5,6,7,8,9)

Để ngữ pháp của chúng ta trở thành một chiến lược ưu tiên hỗn hợp, các điều kiện sau phải được đáp ứng:

a) Thiếu quy định điện tử

b) Có quy tắc nào theo đó x SAU A không? MỘT ĐỈNH x = ?

c) A -> bYg

và điều cần thiết là TRONG SAU x? B CHỨNG x = ?

nghĩa là, trong ngữ pháp, chúng sẽ được thực thi IN SAU x hoặc A SAU x, trong đó x là ký hiệu vị ngữ của chuỗi b.

a) ĐẦU TIÊN"(PG)=(PG?)

FIRST"(RG) = FIRST(DE) = (RG, v,:, i,;)

ĐẦU TIÊN" (AL) = ĐẦU TIÊN (b LE e)= (AL, b, e)

ĐẦU TIÊN" (DE) = ĐẦU TIÊN (v LV: i;) = (DE, v,:, i,;)

ĐẦU TIÊN" (LV) = ĐẦU TIÊN (ID, LV) = (LV, ID)

ĐẦU TIÊN" (OP) =(OP, ID, CO)

ĐẦU TIÊN" (EQ) = ĐẦU TIÊN(ID = EX;) = (EQ, =,;)

ĐẦU TIÊN" (EX) = (EX, SB, -)

ĐẦU TIÊN" (BO) =(B0, +,*,-)

FIRST" (SB) = FIRST((EX)SB) ? FIRST(OP) ? FIRST(BO)=(SB, (,), OP, BO);

ĐẦU TIÊN" (LE) = ĐẦU TIÊN(EQ) = (LE, (,), =,;, f, t, d, n, w, r)

ĐẦU TIÊN" (UO) = (UO,-)

ĐẦU TIÊN" (ID)= ĐẦU TIÊN" (u) = (u)

ĐẦU TIÊN" (CO) = ĐẦU TIÊN" (k) = (k) ĐẦU TIÊN" (e) =( e)

ĐẦU TIÊN" (b) =( b)

ĐẦU TIÊN" (e) =( e)

ĐẦU TIÊN" (v) =( v)

ĐẦU TIÊN" (w) =( w)

ĐẦU TIÊN" (r) =( r)

ĐẦU TIÊN" (i) =( i)

ĐẦU TIÊN" (f) =( f)

ĐẦU TIÊN" (d) =(d)

ĐẦU TIÊN" (n) =( n)

ĐẦU TIÊN" (c) =( c)

ĐẦU TIÊN" (+) =( +)

ĐẦU TIÊN" (*) =( *)

ĐẦU TIÊN" (-) =( -)

ĐẦU TIÊN" (,) =(,)

ĐẦU TIÊN" (;) =(;)

ĐẦU TIÊN" (:) =(:)

ĐẦU TIÊN" (=) = ( = )

ĐẦU TIÊN" (() =(()

ĐẦU TIÊN" ()) =() )

ĐẦU TIÊN" (u) = (u)

ĐẦU TIÊN" (k) =(k)

b) TRACE `(AL) = (?)? TRACE"(PG)=(?,b,e)

TIẾP THEO ` (DE) = (?)?FIRST"(AL)= (?, b, e)

TIẾP THEO ` (LV) = (?)?FIRST"(:)= (?,:)

TIẾP THEO ` (OP) = (?)?FIRST"(SB)= (?,;,), d, t, +, -, *)

TRACK ` (EQ) = (?)?FIRST"(LE)=(?, (,),;, f, =, t, d, n,w,r )

TRACK ` (EX) = (?)?FIRST"(t)?FIRST"(d)?FIRST"(;)?FIRST"())=(?, t,d,;,))

TIẾP THEO ` (BO) = (?)?FIRST"(SB)= (?, (,), OP, BO)

TIẾP THEO ` (UO) = (?)?FIRST"(SB)= (?, (,), OP, BO)

TRACE `(SB) = (?)? TRACE"(EX)= (?, t,d,;,), +, *, -)

TRACK ` (LE) = (?) ?FIRST"(e) ?FIRST"(n) = (?, e, n)

DÒNG `(ID)= (?)? TIẾP THEO" (OP) ? ĐẦU TIÊN" (=) =(?,;,), d, t, +, -, *, =)

TRACE `(CO) = (?)? TRACE" (OP)= (?,;,), d, t, +, -, *, =)

TIẾP THEO ` (b) =(?)?FIRST"(LE)= (?, u, =,;)

TRACE ` (e) =(?)? TRACE"(AL)= (?, b)

TIẾP THEO ` (v) =(?)?FIRST"(LV)= (?, u)

TIẾP THEO ` (w) =(?)?FIRST"(()= (?, ()

TIẾP THEO ` (r) =(?)?FIRST"(() = (?, ()

TIẾP THEO ` (i) =(?)?FIRST"(;)= (?,; )

TIẾP THEO ` (f) =(?)?FIRST"(ID) = (?, u)

TIẾP THEO ` (d) =(?)?FIRST"(LE)= (?, u, =,;)

TIẾP THEO ` (n) =(?)?FIRST"(i) = (?, i )

TRACE ` (+) =(?)? TRACE"(IN) = (?, +,*,-)

TRACE ` (-) =(?)? TRACE"(IN) = (?, +,*,-)

TRACE ` (*) =(?)? TRACE"(IN) = (?, +,*,-)

TRACK ` (;) =(?)?TRACK" (DE)?TRACK `(LE1)?TRACK" (EQ) = (?, b, e, l, u)

TIẾP THEO ` (:) =(?)?FIRST"(i)= (?, i )

TIẾP THEO ` (=) = (?)?FIRST"(EX) = (? (,), u, k, +, -, *)

TIẾP THEO ` (() =(?)?FIRST"(DE)= (?, v,:, i,;)

TRACE ` ()) =(?)? ĐẦU TIÊN"(;) = (?,; )

TRACE ` (,) =(?)? ĐẦU TIÊN"(LV) = (?, u)

TRACE `(u) =(?)? ĐẦU TIÊN" (ID)= ( u, ?)

TRACE `(k) =(?)? ĐẦU TIÊN (CO)= (?, k)

c) PG ->DE AL

AL SAU DE = (b,e) SAU DE = ((b DE), (e DE) )

e SAU LE = ((e LE))

LE SAU b = ((,), =,;, f, t, d, n, w, r) SAU b = (((b), ()b), (=b), (;b), ( f b), (t b), (d b), (n b), (w b), (r b))

;SAU tôi = ((; i))

tôi SAU: = ( (i:) )

: SAU LV = ( (: LV) )

LV SAU v = ( (ID, v) )

LV SAU, = ((ID,))

SAU ID = ((,u))

LE SAU EQ = ((,), =,;, f, t, d, n, w, r ) SAU EQ = (((EQ), () EQ), (= EQ), (; EQ), ( f EQ), (t EQ), (d EQ), (n EQ), (w EQ), (r EQ))

LE -> r (DE);

; SAU) = ((;)))

) SAU DE = (((DE))

DE SAU (= (= ((v)), (:)), (i)), (;)), (e)))

(SAU r = (((r))

LE -> w (DE);

; SAU) = ((;)))

) DE CUỐI CÙNG = (((DE))

DE SAU (= ((v)), (:)), (i)), (;)), (e)))

(SAU w = (((w))

LE -> f ID = EX t EX d LE n;

; SAU n = ((;n))

n SAU LE = ((n, LE))

LE SAU d = (((,), =,;, f, t, d, n, w, r)) ? SAU d = (((d), ()d), (;d), (f d), (t d), (d d), (n d), (w d), (r d))

d SAU EX = ((d, EX))

EX SAU t = (BO, -) ? SAU t = ((BO t), (- t))

t SAU EX = ( t EX)

EX SAU = = ((BO, -) ? SAU = = ((BO =), (- =))

SAU ID = ((= ID))

ID SAU f = ((ID f))

EQ -> ID = EX;

; SAU EX = ((; EX )

EX SAU = = (BO, -) ? SAU = = ((BO =), (- =))

SAU u = ( (=u))

SB SAU UO = ( (,), OP, BO ) SAU UO = (((UO), (OP UO), (BO UO) )

) SAU EX = ( ()EX) )

EX SAU (= (BO, -) ? SAU (= ((BO(), (-())

SB->SB BO SB

SB SAU BO = ((,), OP, BO) SAU BO = (((BO), ()BO), (OP BO), (BO BO))

BO SAU SB = (+,*,-) SAU SB = ((+SB), (*SB), (-SB))

ID SAU u = ((u, u))

G) PG ->DE AL

AL BỘ SƯU TẬP PG = AL BỘ SƯU TẬP TRAIL" (PG) = ((AL ?))

e BỘ SƯU TẬP AL = e DÒNG BỘ SƯU TẬP"(AL)= ((eb), (e?))

=; THEO DÕI BỘ SƯU TẬP"(DE) = ((;b), (;?))

BỘ SƯU TẬP LV LV = DÒNG BỘ SƯU TẬP LV" (LV) = ((LV:), (LV?))

BỘ SƯU TẬP ID LV = THEO DÕI BỘ SƯU TẬP ID" (LV) = ((ID:), (ID ?))

; THU GỌN LE =; THEO DÕI BỘ SƯU TẬP" (LE) = ((; e), (;?), (; n))

LE -> f ID = EX t EX d LE n;

; THU GỌN LE =; THEO DÕI BỘ SƯU TẬP" (LE) = ((; e), (;?), (; n))

BỘ SƯU TẬP EQ LE = EQ COVER TRACE" (LE) = ((EQ e), (EQ?), (EQ n))

EQ -> ID = EX;

; SẴN EQ =; THEO DÕI BỘ SƯU TẬP" (EQ) = ((; (), (;)), (;;), (;f), (;?), (;=), (;t), (;d), (; n), (;w), (;r))

SB BỘ SƯU TẬP EX = SB COVER TRACE" (EX) = ((SB t), (SB?), (SB d), (SB)), (SB;), (SB(), (SB=), (SBf ), (SBn), (SBw), (SBr) )

) BỘ SƯU TẬP SB = SB DẤU HIỆU BỘ SƯU TẬP" (SB) = (() t), ()?), () d), ())), ();))

OP BỘ SƯU TẬP SB = OP BỘ SƯU TẬP DẤU HIỆU" (SB) = ((OP t), (OP ?), (OP d), (OP)), (OP;))

SB->SB BO SB

SB BỘ SƯU TẬP SB = SB COVER TRACE" (SB) = ((SB, t), (SBd), (SB;). (SB)), (SB+), (SB-), (SB*), (SB? ) }

BỘ SƯU TẬP UO = - BỘ SƯU TẬP" (UO) = ( (-?), (--))

BỘ SƯU TẬP = + THEO DÕI BỘ SƯU TẬP" (BO) = ((++), (+?), (+*), (+-))

* BỘ SƯU TẬP = * BỘ SƯU TẬP" (BO) = ((*+), (*?), (**), (*-))

BỘ SƯU TẬP = - BỘ SƯU TẬP" (BO) = ((-+), (-?), (-*), (--))

THU THẬP ID OP = THEO DÕI BẢO HIỂM ID" (OP) = ((ID+), (ID?), (ID*), (ID-))

CO COVER OP = CO COVER DẤU HIỆU" (OP) = ((CO+), (CO?), (CO*), (CO-), (CO;), (COd), (COt), (CO)))

BỘ SƯU TẬP ID ID = THEO DÕI BỘ SƯU TẬP ID" (ID) = ((ID)), (ID ?), (ID k), (ID+), (ID-), (ID*), (ID=), (IDt) , (ID)))

u ID BỘ SƯU TẬP = l THEO DÕI BỘ SƯU TẬP" (ID) = ((u)), (u?), (uk), (u+), (u-), (u*), (u=), (ut), (ud)))

CO BÌA CO = CO BÌA DẤU" (CO) = (CO+), (CO?), (CO*), (CO-), (CO;), (COd), (COt), (CO)))

k BỘ SƯU TẬP CO = k BỘ SƯU TẬP DẤU VẬT" (CO) = (k+), (k?), (k*), (k-), (k;), (kd), (kt), (k)))

Một người được tìm thấy tình huống xung đột khi thu gọn các quy tắc

OP ->ID và ID ->u ID

Ta nhập ID1 -> ID nên viết lại quy tắc ID1 -> u ID

Vì vậy, chúng tôi sẽ thực hiện các hoạt động tích chập.

ID1 BỘ SƯU TẬP ID = ID1 BỘ SƯU TẬP" (ID) = ((ID1)), (ID1 ?), (ID1 k), (ID1+), (ID1-), (ID1*), (ID1=), (ID1t) , (ID1d)))

Với mỗi cặp (x, A)? x SAU A chúng ta xây dựng hàm chuyển đổi xác định hành động truyền??(S 0 , x, A) = (S 0 , A)

? (S0,b,DE) = (S0,DEb)

? (S0,e,DE) = (S0,DEe)

? (S0, e, LE) = (S0, LEe)

? (S0,), b) = (S0, b))

? (S0,;, b) = (S0, b;)

? (S0, (, b) = (S0, b()

? (S0, =, b) = (S0, b=)

? (S0,f,b) = (S0,bf)

? (S0,t,b) = (S0,bt)

? (S0, d, b) = (S0, bd)

? (S0,n,b) = (S0,bn)

? (S0,w,b) = (S0,bw)

? (S0,r,b) = (S0,br)

? (S0,;,i) = (S0,i;)

? (S0, tôi, :) = (S0, tôi :)

? (S0,:LV) = (S0,LV:)

? (S0,ID,v) = (S0,vID)

? (S0,ID,) = (S0,ID)

? (S0, u) = (S0, u,)

? (S0, (, EQ)= (S0, EQ()

? (S0,), EQ)= (S0, EQ))

? (S0, =, EQ)= (S0, EQ=)

? (S0,;, EQ)= (S0, EQ;)

? (S0, f, EQ)= (S0, EQf)

? (S0, t, EQ)= (S0, EQt)

? (S0, d, EQ)= (S0, EQd)

? (S0, n, EQ)= (S0, EQn)

? (S0, w, EQ)= (S0, EQw)

? (S0, r, EQ)= (S0, EQr)

? (S0,;,)) = (S0,);)

? (S0, (, DE) = (S0, DE()

? (S0,v,)) = (S0,)v)

? (S0,;,)) = (S0,);)

? (S0, i,)) = (S0,)i)

? (S0,:,)) = (S0,):)

? (S0,e,)) = (S0,)e)

? (S0, (, r) = (S0, r()

? (S0, (, w) = (S0, w()

? (S0,;,n) = (S0,n;)

? (S0,n,LE) = (S0,LEn)

? (S0, (, d) = (S0, d()

? (S0,), d) = (S0, d))

? (S0,;, d) = (S0, d;)

? (S0,f,d) = (S0,df)

? (S0,t,d) = (S0,dt)

? (S0, d, d) = (S0, đ)

? (S0,n,d) = (S0,dn)

? (S0, w, d) = (S0, dw)

? (S0,r,d) = (S0,dr)

? (S0, d, EX) = (S0, EXd)

? (S0, BO, t) = (S0, tBO)

? (S0, -, t) = (S0, t-)

? (S0, t, EX) = (S0, EXt)

? (S0, BO, =) = (S0, =BO)

? (S0, -, =) = (S0, =-)

? (S0, =, ID) = (S0, ID=)

? (S0, ID, f) = (S0, fID)

? (S0,;,EX) = (S0, EX;)

? (S0, =, u) = (S0, u=)

? (S0, (, UO) = (S0, UO()

? (S0, OP, UO) = (S0, UO OP)

? (S0, BO, UO) = (S0, UO BO)

? (S0,), EX) = (S0, EX))

? (S0, BO, () = (S0, (BO)

? (S0, BO, -) = (S0, -BO)

? (S0, (, BO) = (S0, BO()

? (S0,),BO) = (S0,)BO)

? (S0, OP, BO) = (S0, BOOP)

? (S0, +, SB) = (S0, SB+)

? (S0, *, SB) = (S0, SB*)

? (S0, -, SB) = (S0, SB-)

? (S0,u,u) = (S0,u)

Với mỗi cặp (x, A)? Và CONVERT x chúng ta xây dựng hàm chuyển tiếp xác định hành động tích chập?? * (S 0 , x, bA) = (S 0 , B), trong đó B->bA

? * (S0, AL, ?) = (S0, PG)

? * (S0, e, b) = (S0, AL)

? * (S0, n, ?) = (S0, AL)

? * (S 0 ,;, b) = (S 0 , DE)

? * (S 0 ,;, ?) = (S 0 , DE)

? * (S 0 ,;, e) = (S 0 , DE)

? * (S 0 , LV,:) = (S 0 , LV)

? * (S 0 , LV, ?) = (S 0 , LV)

? * (S 0 , ID, ?) = (S 0 , LV)

? * (S 0 , ID, e) = (S 0 , LV)

? * (S 0 ,;, e) = (S 0 , LE)

? * (S 0 ,;, ?) = (S 0 , LE)

? * (S 0 ,;, n) = (S 0 , LE)

? * (S0, EQ, n) = (S0, LE)

? * (S0, EQ, e) = (S0, LE)

? * (S 0 , EQ, ?) = (S 0 , LE)

? * (S 0 ,;, e) = (S 0 , LE)

? * (S 0 ,;, ?) = (S 0 , LE)

? * (S 0 ,;, () = (S 0 , EQ)

? * (S 0 ,;,)) = (S 0 , EQ)

? * (S 0 ,;, f) = (S 0 , EQ)

? *(S0 ,;, =) = (S0 , EQ)

? * (S 0 ,;, t) = (S 0 , EQ)

? * (S 0 ,;, d) = (S 0 , EQ)

? * (S 0 ,;, n) = (S 0 , EQ)

? * (S 0 ,;, w) = (S 0 , EQ)

? * (S 0 ,;, r) = (S 0 , EQ)

? * (S 0 , SB, ?) = (S 0 , EX)

? * (S 0 , SB, d) = (S 0 , EX)

? * (S 0 , SB,)) = (S 0 , EX)

? * (S 0 , SB,;) = (S 0 , EX)

? * (S 0 , SB, w) = (S 0 , EX)

? * (S 0 , SB, r) = (S 0 , EX)

? * (S 0 , SB, f) = (S 0 , EX)

? * (S 0 , SB, =) = (S 0 , EX)

? * (S 0 , SB, t) = (S 0 , EX)

? * (S0, SB, ?) = (S0, SB)

? * (S 0 , SB, () = (S 0 , SB)

? * (S 0 , SB,)) = (S 0 , SB)

? * (S0, SB, u) = (S0, SB)

? * (S0, SB, k) = (S0, SB)

? * (S0, SB, +) = (S0, SB)

? * (S0, SB, -) = (S0, SB)

? * (S0, SB, *) = (S0, SB)

? * (S0, SB, e) = (S0, SB)

? * (S 0 ,), t) = (S 0 , SB)

? * (S 0 ,), ?) = (S 0 , SB)

? * (S 0 ,), t) = (S 0 , SB)

(S 0 ,),)) = (S 0 , SB)

? * (S 0 ,),;) = (S 0 , SB)

? * (S 0 , -, ?) = (S 0 , UO)

? * (S 0 , -, -) = (S 0 , UO)

? * (S0 , +, +) = (S0 , BO)

? * (S0 , +, ?) = (S0 , BO)

? * (S0 , +, *) = (S0 , BO)

? * (S0 , -, +) = (S0 , BO)

? * (S 0 , -, ?) = (S 0 , BO)

? * (S0 , -, *) = (S0 , BO)

? * (S0 , -, -)) = (S0 , BO)

? * (S0 , *, +) = (S0 , BO)

? * (S0, *, ?) = (S0, BO)

? * (S0, *, *) = (S0, BO)

? * (S0 , *, -)) = (S0 , BO)

? * (S 0 , u, +) = (S 0 , BO)

? * (S 0 , u, ?)= (S 0 , BO)

? * (S 0 , u, *) = (S 0 , BO)

? * (S 0 , u, -)) = (S 0 , BO)

? * (S0, k, +) = (S0, BO)

? * (S0, k, ?) = (S0, BO)

? * (S0, k, *) = (S0, BO)

? * (S 0 , k, -)) = (S 0 , BO)

? * (S0, CO, ?) = (S0, OP)

? * (S0, CO, +) = (S0, OP)

? * (S0, CO, *) = (S0, OP)

? * (S0, CO, -) = (S0, OP)

? * (S 0 , CO,;) = (S 0 , OP)

? * (S0, CO, d) = (S0, OP)

? * (S0, CO, t) = (S0, OP)

? * (S 0 , ID, -) = (S 0 , OP)

? * (S 0 , ID, *) = (S 0 , OP)

? * (S 0 , ID, ?) = (S 0 , OP)

? * (S 0 , ID, () = (S 0 , OP)

? * (S 0 , ID,)) = (S 0 , OP)

? * (S 0 , ID, u) = (S 0 , OP)

? * (S 0 , ID, k) = (S 0 , OP)

? * (S 0 , ID, -) = (S 0 , OP)

? * (S 0 , ID, +) = (S 0 , OP)

? * (S 0 , u,)) = (S 0 , I OP)

? * (S 0 , ID1, *) = (S 0 , ID)

? * (S0, ID1, ?) = (S0, ID)

? * (S 0 , ID1, () = (S 0 , ID)

? * (S 0 , ID1,)) = (S 0 , ID)

? * (S 0 , ID1, u) = (S 0 , ID)

? * (S 0 , ID1, k) = (S 0 , ID)

? * (S 0 , ID1, -) = (S 0 , ID)

? * (S 0 , ID1, +) = (S 0 , ID)

? * (S 0 , u,)) = (S 0 , ID)

? * (S 0 , u, ?) = (S 0 , BO)

? * (S 0 , u, k) = (S 0 , ID)

? * (S 0 , u, *)) = (S 0 , ID)

? * (S 0 , u, -)) = (S 0 , ID)

? * (S 0 , u, +)) = (S 0 , ID)

? * (S 0 , u, d)) = (S 0 , ID)

? * (S 0 , u, t)) = (S 0 , ID)

? * (S 0 , u, =)) = (S 0 , ID)

? * (S0, CO, ?) = (S0, CO)

? * (S0, CO, +) = (S0, CO)

? * (S0, CO, -) = (S0, CO)

? * (S0, CO, *) = (S0, CO)

? * (S0, CO,;) = (S0, CO)

? * (S0, CO, d) = (S0, CO)

? * (S0, CO, t) = (S0, CO)

? * (S0, CO,)) = (S0, CO)

? * (S0, k, +) = (S0, CO)

? * (S0, k, -) = (S0, CO)

? * (S0, k, *) = (S0, CO)

? * (S0, k,;) = (S0, CO)

?? * (S0, k, d) = (S0, CO)

? * (S0, k, t) = (S0, CO)

? * (S0, k,)) = (S0, CO)

? * (S0, k, () = (S0, CO)

2.2.3 Triển khai phần mềm của trình phân tích cú pháp

Bộ phân tích cú pháp (trình phân tích cú pháp) đọc tệp từ vựng do bộ phân tích từ vựng tạo ra, thực hiện phân tích cú pháp ngữ pháp và đưa ra các thông báo về lỗi cú pháp nếu có và tạo một dạng trung gian để ghi lại chương trình gốc. Cơ sở để phát triển trình phân tích cú pháp là việc thiết kế và triển khai máy tạp chí tương ứng.

Để phân tích cú pháp từ dưới lên cho trình phân tích cú pháp từ dưới lên xác định sau khi giảm nó thành đúng loại Cần phải sử dụng các hàm SAU và ROLL để thiết kế một máy lưu trữ có mô tả chi tiết về tất cả các chuyển đổi trong hàm chuyển đổi.

Khi phát triển máy bán hàng tự động, chúng tôi đã xây dựng các hàm chuyển đổi làm cơ sở cho trình phân tích cú pháp. Tất cả các hàm chuyển tiếp có thể được chia thành hai loại:

Chu kỳ hoạt động của máy tạp chí không đọc ký hiệu đầu vào (chu kỳ trống);

Nguyên tắc vận hành máy tạp chí với việc đọc ký hiệu đầu vào.

Khi triển khai bộ phân tích từ vựng, chúng tôi chia chương trình thành các từ vựng và viết chúng thành một danh sách. Sau đó chúng tôi xử lý danh sách này trong trình phân tích cú pháp. Chúng tôi gửi chương trình (danh sách), ký hiệu ban đầu (PG) và điểm đánh dấu dưới cùng của máy tạp chí (h0) đến đầu vào, sau đó chúng tôi chọn chức năng cần thiết transition và một cuộc gọi đệ quy được thực hiện.

Sơ đồ của chương trình phân tích cú pháp được hiển thị trong Phụ lục B trong Hình B.2.

2.2.4 Phát triển mô-đun phiên dịch

Khi phát triển mô-đun thông dịch dưới dạng trung gian của chương trình gốc Dạng ký hiệu hậu tố thường được sử dụng nhiều nhất, giúp thực hiện quá trình thực hiện (thông dịch) chương trình đã dịch khá dễ dàng.

Chúng ta hãy xem xét các nguyên tắc cơ bản của việc hình thành và thực hiện dạng hậu tố của cách viết biểu thức.

Các quy tắc cơ bản để chuyển một biểu thức trung tố thành một biểu thức hậu tố như sau.

Các toán hạng đọc được thêm vào ký hiệu hậu tố và các thao tác được ghi vào ngăn xếp.

Nếu thao tác ở đầu ngăn xếp có mức độ ưu tiên cao hơn (hoặc bằng) so với thao tác hiện đang đọc thì thao tác trên ngăn xếp sẽ được thêm vào mục nhập hậu tố và thao tác hiện tại sẽ được đẩy lên ngăn xếp. Ngược lại (ở mức ưu tiên thấp hơn), chỉ thao tác hiện tại được đẩy lên ngăn xếp.

Dấu ngoặc đơn mở đã đọc được đẩy vào ngăn xếp.

Sau khi đọc dấu ngoặc nhọn đóng, tất cả các thao tác cho đến dấu ngoặc nhọn mở đầu tiên sẽ được lấy ra khỏi ngăn xếp và được thêm vào mục nhập hậu tố, sau đó cả dấu ngoặc nhọn mở và dấu ngoặc đóng đều bị loại bỏ, tức là. không được đặt trên bản ghi postfix hoặc trên ngăn xếp.

Sau khi toàn bộ biểu thức được đọc, các thao tác còn lại trên ngăn xếp sẽ được thêm vào mục nhập hậu tố.

Ký hiệu hậu tố của một biểu thức cho phép nó được tính như sau.

Nếu mã thông báo là toán hạng, nó sẽ được ghi vào ngăn xếp. Nếu mã thông báo là một thao tác thì thao tác đã chỉ định sẽ được thực hiện trên các phần tử cuối cùng (phần tử cuối cùng) được ghi vào ngăn xếp và các phần tử (phần tử) đó sẽ được thay thế trên ngăn xếp bằng kết quả của thao tác.

Nếu việc phân tích từ vựng và cú pháp đã được hoàn thành thành công thì chúng ta sẽ tiến hành diễn giải. Đầu tiên, chúng ta đặt câu từ các từ, sau đó chúng ta dịch các biểu thức thành ký hiệu hậu tố và tính toán.

Sơ đồ hoạt động của trình thông dịch được trình bày tại Phụ lục B trong Hình B.3.

2.3 Mã hóa

Chương trình được triển khai bằng C# trong môi trường lập trình Visual Studio 2010. Nội dung của chương trình được trình bày trong Phụ lục A.

Chương trình bao gồm năm lớp. Giao diện người dùng được triển khai bằng lớp MainForn. Sử dụng lớp LexAnalysis, mô-đun phân tích từ vựng được triển khai, SynAnalysis là mô-đun phân tích cú pháp, Intepreter là mô-đun diễn giải, ProgramisciJakPolska là lớp phụ trợ để chuyển đổi biểu thức thành đảo ngược nhập cảnh Ba Lan(hậu tố).

Mục đích của các thủ tục và chức năng được triển khai trong chương trình được mô tả trong bảng 6,7,8.

Bảng 6 - Mục đích của quy trình và chức năng phân tích từ vựng

Tài liệu tương tự

    Translator là một chương trình hoặc phương tiện kỹ thuật để dịch một chương trình. Xem xét các tính năng chính của việc xây dựng một máy phân tích từ vựng. Giới thiệu các giai đoạn phát triển trình dịch từ một tập hợp con giới hạn của ngôn ngữ cấp cao.

    bài tập khóa học, được thêm vào ngày 06/08/2013

    Thiết kế máy phân tích từ vựng và cú pháp cho ngôn ngữ giáo dục. Quy tắc chuyển đổi biểu thức logicở POLIZ. Hình thành bộ ba, tối ưu hóa danh sách của họ. Cấu trúc logic các chương trình. Kiểm tra các mô-đun biên dịch-thông dịch viên.

    bài tập khóa học, được thêm vào ngày 28/05/2013

    Đặc điểm chung và đánh giá khả năng của ngôn ngữ lập trình C-Sharp, những điểm tương đồng và tính năng đặc biệt từ C++ và Java. Phát triển bộ phân tích từ vựng và cú pháp bằng ngôn ngữ lập trình này. Lập bảng phân tích cú pháp.

    bài tập khóa học, được thêm vào ngày 11/06/2010

    Thiết kế một chương trình phân tích bao gồm hai phần: một bộ phân tích từ vựng chia nhỏ văn bản gốc chương trình từ vựng và điền vào bảng tên; một trình phân tích cú pháp kiểm tra văn bản xem có tuân thủ một ngữ pháp nhất định hay không.

    bài tập khóa học, được thêm vào ngày 14/06/2010

    Viết một chương trình thực hiện phân tích từ vựng và cú pháp của ngôn ngữ lập trình đầu vào, tạo ra một bảng các từ vựng cho biết loại và giá trị của chúng, đồng thời xây dựng một cây cú pháp; văn bản của ngôn ngữ nhập được nhập từ bàn phím.

    bài tập khóa học, được thêm vào ngày 23/02/2012

    Phương pháp phát triển và triển khai một phần trình dịch cho ngôn ngữ C bằng ngôn ngữ C++, chia chuỗi ký tự ban đầu thành các cấu trúc ngôn ngữ không thể phân chia tối thiểu dựa trên từ vựng của ngôn ngữ. Phân tích hoạt động của chương trình.

    bài tập khóa học, được thêm vào ngày 19/03/2012

    Cấu trúc, phân loại và yêu cầu thực hiện trình biên dịch. Thiết kế và triển khai phần phân tích của trình biên dịch ngôn ngữ C++. Các phương pháp thực hiện phân tích từ vựng. Thuật toán cho hoạt động của trình phân tích cú pháp. Nguyên tắc triển khai phần mềm.

    bài tập khóa học, được thêm vào ngày 26/01/2013

    Việc tạo một trình dịch xử lý mã chương trình trong Pascal và sử dụng các toán tử tương đương sẽ tạo ra một chương trình trong C. Các tính năng của đặc tả bên ngoài và hoạt động của máy phân tích từ vựng. Cấu trúc chương trình, hiển thị kết quả trên màn hình.

    bài tập khóa học, được thêm vào ngày 02/07/2011

    Các phương pháp phân tích ngữ pháp. Phát triển cấu trúc của một dịch giả giáo dục dựa trên ngôn ngữ cơ bản Lập trình Object Pascal trong môi trường hướng đối tượng lập trình trực quan Borland DELPHI 6.0 sử dụng hệ điều hành Windows XP.

    bài tập khóa học, được thêm vào ngày 12/05/2013

    Triển khai phần mềm ứng dụng máy tính để bàn bằng ngôn ngữ lập trình C#. Thiết kế và cấu trúc giao diện người dùng, yêu cầu đối với nó và đánh giá chức năng. Phát triển hướng dẫn sử dụng và cách sử dụng nó.