Tóm lại
Các ngôn ngữ lập trình bao gồm một cú pháp đại diện cho chương trình dưới dạng các chuỗi ký tự và một ngữ nghĩa là ý nghĩa dự định của chương trình.
Ngôn ngữ chính thức là cú pháp không có ý nghĩa. Nó có nghĩa là để nghiên cứu cấu trúc của các chuỗi được xác định chính thức, mà không thường gắn ý nghĩa với các chuỗi đó.
Biểu thức chính quy và các hình thức chính thức khác (như Ngữ pháp không ngữ cảnh) được sử dụng để định nghĩa các ngôn ngữ chính thức, được sử dụng làm thành phần cú pháp của lập trình và ngôn ngữ tự nhiên, nghĩa là biểu diễn các câu theo cách có cấu trúc. Các cơ chế khác được sử dụng để liên kết cấu trúc đó với ngữ nghĩa của các ngôn ngữ lập trình.
Phần lớn ở đây được đơn giản hóa đáng kể, đặc biệt là về ngôn ngữ tự nhiên.
Với nhiều chi tiết hơn
Để trả lời câu hỏi của bạn, chúng ta nên bắt đầu lại từ đầu. Một ngôn ngữ theo nghĩa thông thường là, một cách không chính thức, là một phương tiện để truyền đạt thông tin hoặc ý tưởng. Trong một ngôn ngữ, người ta thường phân biệt giữa cú pháp và ngữ nghĩa. Ngữ nghĩa là những gì bạn muốn nói / viết về. thông tin bạn muốn truyền đạt. Cú pháp là phương tiện bạn sử dụng để truyền đạt nó, tức là một đại diện thông thường có thể trao đổi giữa người với người và bây giờ cũng là giữa người và thiết bị hoặc giữa các thiết bị (máy tính).
Thông thường, bạn sẽ sử dụng từ này dog
để truyền đạt ý tưởng của một con chó. Từ dog
này được tạo thành từ ba chữ cái, hoặc một số âm thanh tương đương, và được dự định là đại diện của một loại động vật. Ý tưởng chính là giao tiếp được thực hiện thông qua việc thể hiện những gì sẽ được truyền đạt. Các cấu trúc biểu diễn thường được gọi là cú pháp, trong khi những gì được biểu diễn được gọi là ngữ nghĩa. Điều này ít nhiều xảy ra đối với ngôn ngữ tự nhiên cũng như ngôn ngữ lập trình.
Các từ là các thực thể cú pháp để thể hiện các khái niệm ngữ nghĩa cơ bản ít nhiều. Nhưng những khái niệm cơ bản này phải được kết hợp theo nhiều cách khác nhau để mang lại ý nghĩa phức tạp hơn. Chúng tôi viết
the dog
để truyền đạt rằng chúng tôi có nghĩa là một con chó cụ thể, và the dog bites the cat
để truyền đạt một ý tưởng phức tạp hơn. Nhưng cách các từ được sắp xếp phải được cố định bởi các quy tắc, để chúng ta có thể biết con chó và con mèo nào thực sự cắn con kia.
Vì vậy, chúng tôi có các quy tắc như sentence -> subject verb complement
được cho là khớp các câu và cho chúng tôi biết các ý tưởng liên quan đến từng phần được khớp nối như thế nào. Các quy tắc này là quy tắc cú pháp, vì chúng cho chúng ta biết cách tổ chức thông điệp của chúng ta. Bản subject
thân nó có thể được xác định bởi một quy tắc subject -> article noun
, v.v.
2 x + 1 = 23x123
equation -> expression "=" expression
expression -> expression "+" expression
expression -> number
Cấu trúc của ngôn ngữ lập trình là như nhau. Ngôn ngữ lập trình là chuyên ngành ngữ nghĩa trong việc diễn đạt các tính toán sẽ được thực hiện, thay vì diễn đạt các vấn đề cần giải quyết, bằng chứng về các định lý hoặc quan hệ thân thiện giữa động vật. Nhưng đó là sự khác biệt chính.
Các đại diện được sử dụng trong cú pháp thường là các chuỗi ký tự hoặc âm thanh cho các ngôn ngữ nói. Ngữ nghĩa thường thuộc về miền trừu tượng, hoặc có thể là thực tế, nhưng vẫn được trừu tượng hóa trong các quá trình suy nghĩ của chúng ta hoặc thuộc miền hành vi của các thiết bị. Truyền thông đòi hỏi phải mã hóa thông tin / ý tưởng thành cú pháp, được truyền và giải mã bởi người nhận. Kết quả sau đó được giải thích theo bất cứ cách nào bởi người nhận.
Vì vậy, những gì chúng ta thấy của ngôn ngữ chủ yếu là cú pháp và cấu trúc của nó. Ví dụ trên chỉ là một trong những cách phổ biến nhất để xác định chuỗi cú pháp và tổ chức cấu trúc của chúng. Co nhung nguoi khac. Đối với một ngôn ngữ nhất định, một số chuỗi có thể được gán một cấu trúc và được cho là thuộc về ngôn ngữ, trong khi các chuỗi khác thì không.
Điều này cũng đúng với các từ. Một số chuỗi chữ cái (hoặc âm thanh) là những từ hợp pháp, trong khi một số khác thì không.
Ngôn ngữ chính thức chỉ là cú pháp mà không có ngữ nghĩa. Họ định nghĩa với một bộ quy tắc những chuỗi nào có thể được xây dựng, sử dụng các yếu tố cơ bản của bảng chữ cái. Những gì các quy tắc có thể rất thay đổi, đôi khi phức tạp. Nhưng các ngôn ngữ chính thức được sử dụng cho nhiều mục đích toán học ngoài giao tiếp ngôn ngữ, cho dù là tự nhiên đối với các ngôn ngữ lập trình. Tập hợp các quy tắc xác định các chuỗi trong một ngôn ngữ được gọi là ngữ pháp. Nhưng có nhiều cách khác để định nghĩa ngôn ngữ.
Trong thực tế, một ngôn ngữ được cấu trúc theo hai cấp độ. Cấp độ từ vựng xác định các từ được xây dựng từ bảng chữ cái của các ký tự. Cấp độ cú pháp xác định các câu hoặc chương trình được xây dựng từ bảng chữ cái của các từ (hoặc chính xác hơn là các họ từ, để nó vẫn là một bảng chữ cái hữu hạn). Điều này nhất thiết phải được đơn giản hóa một chút.
Cấu trúc của các từ khá đơn giản trong hầu hết các ngôn ngữ (lập trình hoặc tự nhiên) do đó chúng thường được định nghĩa với loại thường được coi là loại ngôn ngữ chính thức đơn giản nhất: ngôn ngữ thông thường. Chúng có thể được định nghĩa bằng các biểu thức chính quy (regrec) và được xác định khá dễ dàng với các thiết bị được lập trình được gọi là automata trạng thái hữu hạn. Trong các trường hợp của ngôn ngữ lập trình, các ví dụ của một từ là một định danh, một số nguyên, chuỗi, một số thực, một từ dành riêng như if
hoặc repeat
, một ký hiệu dấu chấm câu hoặc dấu ngoặc đơn mở. Ví dụ về họ từ là định danh, chuỗi, số nguyên.
Cấp độ cú pháp thường được xác định bởi một loại ngôn ngữ chính thức phức tạp hơn một chút: ngôn ngữ không ngữ cảnh, sử dụng các từ làm bảng chữ cái. Các quy tắc chúng ta đã thấy ở trên là các quy tắc không ngữ cảnh cho ngôn ngữ tự nhiên. Trong trường hợp các quy tắc ngôn ngữ lập trình có thể là:
statement -> assignment
statement -> loop
loop -> "while" expression "do" statement
assignment -> "identifier" "=" expression
expression -> "identifier"
expression -> "integer"
expression -> expression "operator" expression
Với các quy tắc như vậy bạn có thể viết:
while aaa /= bbb do aaa = aaa + bbb / 6
đó là một tuyên bố.
Và cách nó được tạo ra có thể được biểu diễn bằng cấu trúc cây gọi là cây phân tích cú pháp hoặc cây cú pháp (không hoàn thành ở đây):
statement
|
_______________ loop _______________
/ / \ \
"while" expression "do" statement
__________|_________ |
/ | \ assignment
expression "operator" expression _______|_______
| | | / | \
"identifier" "/=" "identifier" "identifier" "=" expression
| | | |
aaa bbb aaa ... ...
Các tên xuất hiện ở bên trái của một quy tắc được gọi là không phải thiết bị đầu cuối, trong khi các từ được gọi cũng là thiết bị đầu cuối, vì chúng nằm trong bảng chữ cái cho ngôn ngữ (trên cấp độ từ vựng). Non-terminal đại diện cho các cấu trúc cú pháp khác nhau, có thể được sử dụng để soạn chương trình.
Các quy tắc như vậy được gọi là không có ngữ cảnh, bởi vì một thiết bị không đầu cuối có thể được thay thế tùy ý bằng cách sử dụng bất kỳ quy tắc tương ứng nào, độc lập với bối cảnh mà nó xuất hiện. Tập hợp các quy tắc xác định ngôn ngữ được gọi là ngữ pháp không ngữ cảnh.
Trên thực tế, có những hạn chế về điều đó, khi các định danh phải được khai báo đầu tiên hoặc khi một biểu thức phải thỏa mãn các hạn chế loại. Nhưng hạn chế như vậy có thể được coi là ngữ nghĩa, hơn là cú pháp. Trên thực tế một số chuyên gia đặt chúng trong những gì họ gọi là
ngữ nghĩa tĩnh .
Cho bất kỳ câu, bất kỳ chương trình, ý nghĩa của câu đó được trích xuất bằng cách phân tích cấu trúc được đưa ra bởi cây phân tích cho câu này. Do đó, rất quan trọng để phát triển các thuật toán, được gọi là trình phân tích cú pháp, có thể khôi phục cấu trúc cây tương ứng với một chương trình, khi được cung cấp chương trình.
Trình phân tích cú pháp được đi trước bởi bộ phân tích từ vựng nhận ra các từ và xác định họ thuộc về họ. Sau đó, chuỗi các từ, hoặc các yếu tố từ vựng, được đưa cho trình phân tích cú pháp lấy cấu trúc cây bên dưới. Từ cấu trúc này, trình biên dịch có thể xác định cách tạo mã, phần ngữ nghĩa của phần xử lý chương trình ở phía trình biên dịch.
Trình phân tích cú pháp của trình biên dịch thực sự có thể xây dựng một cấu trúc dữ liệu tương ứng với cây phân tích cú pháp và chuyển nó sang các giai đoạn sau của quá trình biên dịch, nhưng nó không phải. Chạy số lượng thuật toán phân tích cú pháp để phát triển một chiến lược tính toán để khám phá cây cú pháp ẩn trong văn bản chương trình. Cây cú pháp / phân tích cú pháp này có thể hoặc không thể được khám phá trong quá trình, tùy thuộc vào chiến lược biên dịch (số lượng giai đoạn). Điều cần thiết là cuối cùng có ít nhất một cuộc thăm dò từ dưới lên của cây phân tích, cho dù được khám phá hay để lại ẩn trong cấu trúc tính toán.
Lý do cho điều đó, theo trực giác, là một cách chính thức tiêu chuẩn để xác định ngữ nghĩa liên quan đến cấu trúc cây cú pháp là bằng cách gọi là đồng cấu. Đừng sợ từ lớn. Ý tưởng chỉ là xem xét ý nghĩa của tổng thể được xây dựng từ ý nghĩa của các bộ phận, trên cơ sở toán tử kết nối chúng
Ví dụ, câu the dog bites the cat
có thể được phân tích với quy tắc sentence -> subject verb complement
. Biết ý nghĩa của 3 cây con subject
, verb
và complement
, quy tắc sáng tác chúng cho chúng ta biết rằng đối tượng đang thực hiện hành động và con mèo là người bị cắn.
Đây chỉ là một lời giải thích trực quan, nhưng nó có thể được chính thức hóa. Ngữ nghĩa được xây dựng đi lên từ các thành phần. Nhưng điều này ẩn giấu rất nhiều phức tạp.
Công việc nội bộ của trình biên dịch có thể được phân tách thành nhiều giai đoạn. Trình biên dịch thực tế có thể làm việc theo từng giai đoạn, sử dụng các biểu diễn trung gian. Nó cũng có thể hợp nhất một số giai đoạn. Điều này phụ thuộc vào công nghệ được sử dụng và mức độ phức tạp của việc biên dịch ngôn ngữ trong tay.