Tại sao ngữ pháp mơ hồ xấu?


30

Tôi hiểu rằng nếu tồn tại 2 hoặc nhiều cây phái sinh trái hoặc phải, thì ngữ pháp là mơ hồ, nhưng tôi không thể hiểu tại sao nó tệ đến mức mọi người đều muốn loại bỏ nó.


1
Liên quan nhưng không giống nhau: softwareengineering.stackexchange.com/q
4323872/206652


1
Thật vậy, hình thức rõ ràng là tốt hơn cho sử dụng thực tế, hình thức rõ ràng sử dụng ít quy tắc sản xuất xây dựng cây nhỏ hơn ở mức cao (do đó trình biên dịch hiệu quả - mất ít thời gian hơn để phân tích). Hầu hết các công cụ cung cấp khả năng giải quyết sự mơ hồ rõ ràng ngoài ngữ pháp.
Grijesh Chauhan

3
"Mọi người đều muốn thoát khỏi nó". Chà, điều đó không đúng. Trong các ngôn ngữ có liên quan đến thương mại, người ta thường thấy sự mơ hồ được thêm vào khi ngôn ngữ phát triển. Ví dụ, C ++ cố tình thêm sự mơ hồ std::vector<std::vector<int>>vào năm 2011, trước đây thường yêu cầu một khoảng trống giữa >>trước đó. Cái nhìn sâu sắc quan trọng là các ngôn ngữ này có nhiều người dùng hơn nhà cung cấp, do đó, việc khắc phục một sự phiền toái nhỏ cho người dùng biện minh cho rất nhiều công việc của những người triển khai.
MSalters

Câu trả lời:


52

Hãy xem xét ngữ pháp sau cho các biểu thức số học: Hãy xem xét biểu thức sau: Giá trị của nó là gì? Đây là hai cây phân tích có thể:

XX+XXXXXX/Xvarconst
abc

(X - X) - X nhập mô tả hình ảnh ở đây

Theo cái bên trái, chúng ta nên hiểu là , đó là cách giải thích thông thường. Theo người bên phải, chúng ta nên hiểu nó là , có lẽ không phải là mục đích.abc(ab)ca(bc)=ab+c

Khi biên dịch một chương trình, chúng tôi muốn việc giải thích cú pháp không rõ ràng. Cách dễ nhất để thực thi điều này là sử dụng một ngữ pháp rõ ràng. Nếu ngữ pháp không rõ ràng, chúng ta có thể cung cấp các quy tắc ngắt kết nối, như quyền ưu tiên của toán tử và tính kết hợp. Các quy tắc này có thể được thể hiện tương đương bằng cách làm cho ngữ pháp không rõ ràng theo một cách cụ thể.


Cây phân tích cú pháp được tạo bằng cách sử dụng trình tạo cây cú pháp .


12
@HIRAKMONDAL Thực tế là cú pháp mơ hồ không phải là vấn đề thực sự. vấn đề là hai cây phân tích khác nhau có hành vi khác nhau. Nếu ngôn ngữ của bạn có ngữ pháp mơ hồ nhưng tất cả các cây phân tích cho một biểu thức đều tương đương về mặt ngữ nghĩa thì đó sẽ không phải là vấn đề (ví dụ: lấy ví dụ Yuval và xem xét trường hợp toán tử duy nhất của bạn +).
Bakuriu

14
@Bakuriu Những gì bạn nói là đúng, nhưng "tương đương về mặt ngữ nghĩa" là một thứ tự cao. Ví dụ, số học dấu phẩy động thực sự không liên kết (vì vậy hai cây "+" sẽ không tương đương). Ngoài ra, ngay cả khi câu trả lời được đưa ra theo cùng một cách, thứ tự đánh giá không xác định rất quan trọng trong các ngôn ngữ mà các biểu thức có thể có tác dụng phụ. Vì vậy, những gì bạn nói là đúng về mặt kỹ thuật nhưng trong thực tế, sẽ rất bất thường khi sự mơ hồ của một ngữ pháp không có tác động đến việc sử dụng ngữ pháp đó.
Richard Rast

Một số ngôn ngữ hiện nay kiểm tra tràn số nguyên trong các bổ sung, do đó, ngay cả a + b + c cho các số nguyên phụ thuộc vào thứ tự đánh giá.
gnasher729

3
Thậm chí tệ hơn, trong một số trường hợp, ngữ pháp không cung cấp bất kỳ cách nào để đạt được ý nghĩa thay thế. Tôi đã thấy điều này trong các ngôn ngữ truy vấn, trong đó việc lựa chọn ngữ pháp thoát (ví dụ: nhân đôi ký tự đặc biệt để thoát nó) làm cho các truy vấn nhất định không thể diễn đạt.
Ngừng làm hại Monica

12

Ngược lại với các câu trả lời hiện có khác [ 1 , 2 ], thực sự có một lĩnh vực ứng dụng, trong đó các ngữ pháp mơ hồ rất hữu ích . Trong lĩnh vực xử lý ngôn ngữ tự nhiên (NLP), khi bạn muốn phân tích ngôn ngữ tự nhiên (NL) bằng ngữ pháp chính thức, bạn đã gặp vấn đề là NL vốn đã mơ hồ ở các cấp độ khác nhau [được chuyển thể từ Koh18, ch. 6.4]:

  • Cú pháp tổng hợp:

    Peter đuổi theo người đàn ông trong chiếc xe thể thao màu đỏ

    Là Peter hay người đàn ông trong chiếc xe thể thao màu đỏ?

  • Ngữ nghĩa ngữ nghĩa:

    Peter đã đến ngân hàng

    Một ngân hàng để ngồi hoặc một ngân hàng để rút tiền từ đâu?

  • Thực dụng ambuigity:

    Hai người đàn ông mang hai cái túi

    Họ đã mang các túi cùng nhau hoặc mỗi người đàn ông mang hai túi?

Các cách tiếp cận khác nhau cho NLP đối phó khác nhau với việc xử lý nói chung và đặc biệt là các hoạt động này. Ví dụ: đường ống của bạn có thể trông như sau:

  1. Phân tích cú pháp NL với ngữ pháp mơ hồ
  2. Đối với mọi AST kết quả: chạy thế hệ mô hình để tạo ra ý nghĩa ngữ nghĩa mơ hồ và loại trừ sự mơ hồ cú pháp không thể từ bước 1
  3. Đối với mọi mô hình kết quả: lưu nó trong bộ nhớ cache của bạn.

Bạn làm đường ống này cho mỗi câu. Càng nhiều văn bản, từ cùng một cuốn sách bạn xử lý, bạn càng có thể loại trừ các mô hình không cần thiết, tồn tại cho đến bước 3, từ các câu trước.

Trái ngược với ngôn ngữ lập trình, chúng ta có thể đưa ra yêu cầu rằng mỗi câu NL đều có ngữ nghĩa chính xác. Thay vào đó, chúng ta chỉ có thể ghi sổ nhiều mô hình ngữ nghĩa có thể trong suốt quá trình phân tích các văn bản lớn hơn. Từ lúc này đến lúc khác, những hiểu biết sau này giúp chúng ta loại trừ những sự mơ hồ trước đó.

Nếu bạn muốn làm bẩn tay với các trình phân tích cú pháp có thể tạo ra nhiều dẫn xuất cho ngữ pháp mơ hồ, hãy xem Khung ngữ pháp . Ngoài ra, [Koh18, ch. 5] có phần giới thiệu về nó cho thấy một cái gì đó tương tự như đường ống của tôi ở trên. Lưu ý rằng vì [Koh18] là các ghi chú bài giảng, các ghi chú có thể không dễ hiểu nếu không có các bài giảng.


Tài liệu tham khảo

[Koh18]: Michael Kohlhase. "Xử lý ngôn ngữ tự nhiên dựa trên logic. Học kỳ mùa đông 2018/19. Ghi chú bài giảng." URL: https://kwarc.info/teaching/LBS/notes.pdf . URL của mô tả khóa học: https://kwarc.info/cifts/lbs/ (bằng tiếng Đức)

[Koh18, ch. 5]: Xem chương 5, "Thực hiện các đoạn: Khung ngữ pháp và logic", trong [Koh18]

[Koh18, ch. 6.4] Xem chương 6.4, "Vai trò tính toán của sự mơ hồ", trong [Koh18]


Cảm ơn rất nhiều .. Tôi đã có cùng nghi ngờ và bạn đã xóa nó .. :)
HIRAK MONDAL

1
Chưa kể các vấn đề với trâu trâu Trâu trâu trâu ... cho một số lượng trâu phù hợp
Hagen von Eitzen

Bạn viết, ngược lại, nhưng tôi gọi đây là mặt khác của đồng tiền từ những gì tôi đã trả lời. Phân tích ngôn ngữ tự nhiên bằng các ngữ pháp mơ hồ của chúng khó đến nỗi các trình phân tích cú pháp truyền thống không thể làm được!
Davislor

1
@ComFalet Tôi nên chính xác hơn ở đây. Một cái nhìn ngắn gọn về GF (Cảm ơn vì liên kết!) Cho thấy rằng nó đọc các ngữ pháp không ngữ cảnh với ba phần mở rộng (như cho phép lặp lại) và trả về một danh sách tất cả các dẫn xuất có thể. Các thuật toán để làm điều đó đã có từ những năm 50. Tuy nhiên, việc có thể xử lý CFG hoàn toàn chung có nghĩa là thời gian chạy trong trường hợp xấu nhất của bạn sẽ nổ tung và trong thực tế, ngay cả khi sử dụng trình phân tích cú pháp chung như GLL, các kỹ sư phần mềm cố gắng sử dụng một tập hợp con CFG, như ngữ pháp LL, có thể được phân tích cú pháp hiệu quả hơn.
Davislor

1
@ComFalet Vì vậy, không phải máy tính không thể xử lý CFG (mặc dù ngôn ngữ tự nhiên không thực sự không có ngữ cảnh và dịch máy thực sự hữu ích sử dụng các kỹ thuật hoàn toàn khác nhau). Đó là, nếu bạn yêu cầu trình phân tích cú pháp của bạn xử lý sự mơ hồ, quy tắc đó sẽ loại bỏ các phím tắt nhất định sẽ làm cho nó hiệu quả hơn.
Davislor

10

Ngay cả khi có một cách được xác định rõ để xử lý sự mơ hồ (ví dụ biểu thức mơ hồ là lỗi cú pháp), các ngữ pháp này vẫn gây ra sự cố. Ngay khi bạn giới thiệu sự mơ hồ vào một ngữ pháp, một trình phân tích cú pháp có thể không còn chắc chắn rằng trận đấu đầu tiên mà nó nhận được là dứt khoát. Nó cần phải tiếp tục thử tất cả các cách khác để phân tích một tuyên bố, để loại trừ bất kỳ sự mơ hồ nào. Bạn cũng không phải đối phó với một thứ đơn giản như ngôn ngữ LL (1), vì vậy bạn không thể sử dụng trình phân tích cú pháp đơn giản, nhỏ, nhanh. Ngữ pháp của bạn có các ký hiệu có thể được đọc theo nhiều cách, vì vậy bạn phải chuẩn bị để quay lại rất nhiều.

Trong một số miền bị hạn chế, bạn có thể thoát khỏi việc chứng minh rằng tất cả các cách có thể để phân tích một biểu thức là tương đương (ví dụ: vì chúng đại diện cho một hoạt động kết hợp). (a + b) + c = a + (b + c).


9

IF a THEN IF b THEN x ELSE ynghĩa là

IF a THEN
    IF b THEN
        x
    ELSE
        y

hoặc là

IF a THEN
    IF b THEN x
ELSE
    y

? AKA vấn đề khác lơ lửng .


1
Đó là một ví dụ tốt cho thấy rằng ngay cả một ngữ pháp không mơ hồ (như trong Java, C, C ++, ...) cho phép sự mơ hồ rõ ràng (!) Từ góc độ con người. Mặc dù chúng tôi chính thức và tính toán tốt, giờ chúng tôi đã có thêm một vấn đề phát triển không có lỗi UX /.
ComFalet

5

Lấy ví dụ phân tích nhiều nhất trong C ++ chẳng hạn:

bar foo(foobar());

Đây có phải là khai báo hàm fookiểu bar(foobar())(tham số là con trỏ hàm trả về a foobar) hay khai báo biến fookiểu intvà được khởi tạo với khởi tạo mặc định foobar?

Điều này được phân biệt trong các trình biên dịch bằng cách giả sử đầu tiên trừ khi biểu thức bên trong danh sách tham số không thể được hiểu là một kiểu.

Khi bạn nhận được một biểu thức mơ hồ như vậy, trình biên dịch có 2 tùy chọn

  1. giả sử rằng biểu thức là một dẫn xuất cụ thể và thêm một số từ chối vào ngữ pháp để cho phép các dẫn xuất khác được thể hiện.

  2. lỗi và yêu cầu định hướng một trong hai cách

Cái đầu tiên có thể rơi ra một cách tự nhiên, cái thứ hai đòi hỏi người lập trình trình biên dịch phải biết về sự mơ hồ.

Nếu sự không rõ ràng này không bị phát hiện thì có thể có hai trình biên dịch khác nhau mặc định cho các dẫn xuất khác nhau cho biểu thức mơ hồ đó. Dẫn đến mã là không di động vì lý do không rõ ràng. Điều này dẫn đến mọi người cho rằng đó là một lỗi trong một trong các trình biên dịch trong khi đó thực sự là một lỗi trong đặc tả ngôn ngữ.


5

Tôi nghĩ rằng câu hỏi chứa một giả định rằng chỉ có đường biên chính xác là tốt nhất.

Trong cuộc sống thực, việc sống với những ngữ pháp mơ hồ là điều khá phổ biến, miễn là chúng không (có thể nói) quá mơ hồ.

Ví dụ: nếu bạn nhìn xung quanh các ngữ pháp được biên dịch bằng yacc (hoặc tương tự, chẳng hạn như bison hoặc byacc), bạn sẽ thấy rằng có khá nhiều cảnh báo về "xung đột N / dịch chuyển" khi bạn biên dịch chúng. Khi yacc gặp phải sự thay đổi / giảm xung đột, điều đó báo hiệu sự mơ hồ trong ngữ pháp.

Tuy nhiên, một sự thay đổi / giảm xung đột thường là một vấn đề khá nhỏ. Trình tạo trình phân tích cú pháp sẽ giải quyết xung đột theo hướng "thay đổi" thay vì giảm. Ngữ pháp là hoàn toàn tốt nếu đó là những gì bạn muốn (và nó dường như hoạt động hoàn toàn tốt trong thực tế).

Xung đột thay đổi / giảm thường phát sinh trong một trường hợp theo thứ tự chung này (sử dụng mũ cho các thiết bị không đầu cuối và chữ thường cho thiết bị đầu cuối):

A -> B | c
B -> a | c

Khi chúng ta gặp phải một c, có một sự mơ hồ: chúng ta nên phân tích ctrực tiếp như một A, hay chúng ta nên phân tích nó như một B, mà đến lượt nó là một A? Trong trường hợp như thế này, yacc và như vậy sẽ chọn tuyến đường đơn giản / ngắn hơn và phân tích cú pháp ctrực tiếp dưới dạng A, thay vì đi tuyến đường c-> B-> A. Điều này có thể sai, nhưng nếu vậy, điều đó có thể có nghĩa là bạn có một lỗi thực sự đơn giản trong ngữ pháp của bạn và bạn không nên cho phép ctùy chọn như một khả năng cho Atất cả.

Bây giờ, ngược lại, chúng ta có thể có một cái gì đó giống như thế này:

A -> B | C
B -> a | c
C -> b | c

Bây giờ khi chúng ta gặp phải một cmâu thuẫn giữa việc nên coi clà a Bhay a C. Có rất ít cơ hội rằng một chiến lược giải quyết xung đột tự động sẽ chọn những gì chúng ta thực sự muốn. Cả hai điều này đều không phải là "sự thay đổi" - cả hai đều là "sự giảm bớt", vì vậy đây là "sự giảm / giảm xung đột" (mà những người quen với yacc và thường nhận ra đó là một vấn đề lớn hơn nhiều so với sự thay đổi / giảm xung đột).

Vì vậy, mặc dù tôi không chắc là tôi đã đi quá xa để nói rằng bất kỳ ai thực sự hoan nghênh sự mơ hồ trong ngữ pháp của họ, trong ít nhất một số trường hợp, nó đủ nhỏ để không ai thực sự quan tâm nhiều về nó. Trong bản tóm tắt, họ có thể thích ý tưởng loại bỏ tất cả sự mơ hồ - nhưng không đủ để luôn thực sự làm điều đó. Ví dụ, một ngữ pháp nhỏ, đơn giản chứa một sự mơ hồ nhỏ có thể thích hợp hơn với một ngữ pháp lớn hơn, phức tạp hơn để loại bỏ sự mơ hồ (đặc biệt là khi bạn đi vào cõi thực tế của việc tạo ra một trình phân tích cú pháp từ ngữ pháp và thấy rằng không rõ ràng ngữ pháp tạo ra một trình phân tích cú pháp sẽ không chạy trên máy mục tiêu của bạn).


người đàn ông, ước gì tôi đã có lời giải thích tuyệt vời này về xung đột giảm ca 5 tháng trước! ^^; +1
Khách sạnCalifornia
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.