Ưu điểm của Antlr (so với nói, lex / yacc / bison) [đã đóng]


143

Trước đây, tôi đã sử dụng lex và yacc (thường là bò rừng) cho các dự án khác nhau, thường là các dịch giả (chẳng hạn như một tập hợp con EDIF được truyền vào ứng dụng EDA). Ngoài ra, tôi đã phải hỗ trợ mã dựa trên ngữ pháp lex / yacc có từ hàng thập kỷ. Vì vậy, tôi biết cách của mình xung quanh các công cụ, mặc dù tôi không phải là chuyên gia.

Tôi đã thấy những bình luận tích cực về Antlr trong nhiều diễn đàn trước đây và tôi tò mò về những gì tôi có thể thiếu. Vì vậy, nếu bạn đã sử dụng cả hai, vui lòng cho tôi biết những gì tốt hơn hoặc cao cấp hơn trong Antlr. Hạn chế hiện tại của tôi là tôi làm việc trong một cửa hàng C ++ và bất kỳ sản phẩm nào chúng tôi gửi sẽ không bao gồm Java, vì vậy các trình phân tích cú pháp kết quả sẽ phải tuân theo quy tắc đó.

Câu trả lời:


145

Cập nhật / cảnh báo: Câu trả lời này có thể đã lỗi thời!


Một điểm khác biệt chính là ANTLR tạo ra trình phân tích cú pháp LL (*), trong khi YACC và Bison đều tạo ra các trình phân tích cú pháp là LALR. Đây là một điểm khác biệt quan trọng đối với một số ứng dụng, rõ ràng nhất là các toán tử:

expr ::= expr '+' expr
       | expr '-' expr
       | '(' expr ')'
       | NUM ;

ANTLR hoàn toàn không có khả năng xử lý ngữ pháp này. Để sử dụng ANTLR (hoặc bất kỳ trình tạo trình phân tích LL nào khác), bạn sẽ cần phải chuyển đổi ngữ pháp này thành một thứ không được đệ quy trái. Tuy nhiên, Bison không có vấn đề với ngữ pháp của hình thức này. Bạn sẽ cần khai báo '+' và '-' là các toán tử liên kết trái, nhưng điều đó không bắt buộc đối với đệ quy trái. Một ví dụ tốt hơn có thể được gửi đi:

expr ::= expr '.' ID '(' actuals ')' ;

actuals ::= actuals ',' expr | expr ;

Lưu ý rằng cả quy tắc expractualsquy tắc đều được đệ quy trái. Điều này tạo ra AST hiệu quả hơn nhiều khi đến lúc tạo mã vì nó tránh được sự cần thiết của nhiều thanh ghi và đổ không cần thiết (một cây nghiêng trái có thể bị sập trong khi cây nghiêng phải không thể).

Về mặt sở thích cá nhân, tôi nghĩ rằng các ngữ pháp LALR dễ dàng hơn rất nhiều để xây dựng và gỡ lỗi. Nhược điểm là bạn phải đối phó với các lỗi hơi khó hiểu như shift-giảm và (giảm đáng sợ). Đây là những lỗi mà Bison mắc phải khi tạo trình phân tích cú pháp, do đó nó không ảnh hưởng đến trải nghiệm của người dùng cuối, nhưng nó có thể làm cho quá trình phát triển thú vị hơn một chút. ANTLR thường được coi là dễ sử dụng hơn YACC / Bison vì lý do này chính xác.


2
Vì vậy, lợi thế lớn, có thể là duy nhất của Antlr trong nhận thức của bạn là nó tạo ra ít lỗi hơn như sr và rr trong giai đoạn xây dựng? Tôi hy vọng tôi sẽ thử, nhưng có lẽ cuối cùng sẽ gắn bó với những gì tôi biết ...
Don Wakefield

1
Vâng, đó là khá nhiều đó. :-) Tôi thực sự không đồng ý với ý kiến ​​phổ biến rằng ANTLR dễ hơn Bison, vì vậy tôi nghĩ tôi sẽ đồng ý với quyết định của bạn.
Daniel Spiewak

2
Liệu quy tắc 'thực tế' có cần quy tắc thứ hai để chỉ ra rằng 'expr' đơn giản là thực tế không? Nếu không, giải thích tốt đẹp.
Jonathan Leffler

8
Một nhận xét khác mà tôi tìm thấy gần đây, mặc dù đã một thập kỷ, đưa ra một quan sát hợp lý về đầu ra : compilers.iecc.com/comparch/article/98-11-040 : "ANTLR / PCCTS là LL khiến cho việc viết ngữ pháp trở nên khó khăn hơn, nhưng mã được tạo ra có thể đọc được. Yacc là LALR (tất nhiên bạn biết điều đó) làm cho việc viết ngữ pháp dễ dàng hơn, nhưng mã được tạo ra cũng có thể là chữ tượng hình. "
Don Wakefield

72
Tôi vừa hoàn thành hỗ trợ đệ quy bên trái ngay lập tức cho ANTLR phiên bản tiếp theo v3.4. Xử lý các quy tắc biểu thức LR và các công cụ tương tự như quy tắc khai báo C. :)
Terence Parr

117

Sự khác biệt đáng kể nhất giữa YACC / Bison và ANTLR là loại ngữ pháp mà các công cụ này có thể xử lý. YACC / Bison xử lý các ngữ pháp LALR, ANTLR xử lý các ngữ pháp LL.

Thông thường, những người đã làm việc với các ngữ pháp LALR trong một thời gian dài, sẽ thấy làm việc với các ngữ pháp LL khó khăn hơn và ngược lại. Điều đó không có nghĩa là các ngữ pháp hoặc công cụ vốn đã khó làm việc hơn. Công cụ nào bạn thấy dễ sử dụng hơn sẽ chủ yếu làm quen với loại ngữ pháp.

Về lợi thế, có những khía cạnh mà ngữ pháp LALR có lợi thế hơn ngữ pháp LL và có những khía cạnh khác mà ngữ pháp LL có lợi thế hơn ngữ pháp LALR.

YACC / Bison tạo các trình phân tích cú pháp điều khiển bảng, có nghĩa là "logic xử lý" được chứa trong dữ liệu của chương trình phân tích cú pháp, không nhiều trong mã của trình phân tích cú pháp. Phần thưởng là ngay cả một trình phân tích cú pháp cho một ngôn ngữ rất phức tạp cũng có dấu chân mã tương đối nhỏ. Điều này quan trọng hơn trong những năm 1960 và 1970 khi phần cứng rất hạn chế. Các trình tạo trình phân tích cú pháp điều khiển bảng quay trở lại thời đại này và dấu chân mã nhỏ là một yêu cầu chính trước đó.

ANTLR tạo ra các trình phân tích cú pháp gốc đệ quy, có nghĩa là "logic xử lý" được chứa trong mã của trình phân tích cú pháp, vì mỗi quy tắc sản xuất của ngữ pháp được biểu thị bằng một hàm trong mã trình phân tích cú pháp. Phần thưởng là việc hiểu trình phân tích cú pháp đang làm gì dễ dàng hơn bằng cách đọc mã của nó. Ngoài ra, các trình phân tích cú pháp gốc đệ quy thường nhanh hơn các trình phân tích cú pháp bảng. Tuy nhiên, đối với các ngôn ngữ rất phức tạp, dấu chân mã sẽ lớn hơn. Đây là một vấn đề trong những năm 1960 và 1970. Trước đó, chỉ có các ngôn ngữ tương đối nhỏ như Pascal được triển khai theo cách này do giới hạn phần cứng.

Các trình phân tích cú pháp được tạo ANTLR thường nằm trong khoảng 10.000 dòng mã và hơn thế nữa. Các trình phân tích cú pháp gốc đệ quy viết tay thường ở trong cùng một sân bóng. Trình biên dịch Oberon của Wirth có lẽ là trình biên dịch nhỏ gọn nhất với khoảng 4000 dòng mã bao gồm cả tạo mã, nhưng Oberon là một ngôn ngữ rất nhỏ gọn chỉ với khoảng 40 quy tắc sản xuất.

Như ai đó đã chỉ ra, một điểm cộng lớn cho ANTLR là công cụ IDE đồ họa, được gọi là ANTLRworks. Nó là một phòng thí nghiệm thiết kế ngữ pháp và ngôn ngữ hoàn chỉnh. Nó hiển thị các quy tắc ngữ pháp của bạn khi bạn nhập chúng và nếu nó tìm thấy bất kỳ xung đột nào, nó sẽ hiển thị cho bạn đồ họa về xung đột là gì và nguyên nhân gây ra nó. Nó thậm chí có thể tự động cấu trúc lại và giải quyết các xung đột như đệ quy trái. Khi bạn có một ngữ pháp không xung đột, bạn có thể để ANTLRworks phân tích một tệp đầu vào của ngôn ngữ của bạn và xây dựng một cây phân tích và AST cho bạn và hiển thị cây theo đồ họa trong IDE. Đây là một lợi thế rất lớn vì nó có thể giúp bạn tiết kiệm nhiều giờ làm việc: Bạn sẽ tìm thấy các lỗi về khái niệm trong thiết kế ngôn ngữ của mình trước khi bạn bắt đầu viết mã! Tôi chưa tìm thấy bất kỳ công cụ nào như vậy cho ngữ pháp LALR, có vẻ như không có công cụ nào như vậy.

Ngay cả với những người không muốn tạo trình phân tích cú pháp của họ nhưng mã hóa chúng, ANTLRworks là một công cụ tuyệt vời để thiết kế / tạo mẫu ngôn ngữ. Khá có thể là công cụ tốt nhất như vậy có sẵn. Thật không may, điều đó không giúp ích gì cho bạn nếu bạn muốn xây dựng trình phân tích cú pháp LALR. Chuyển đổi từ LALR sang LL chỉ đơn giản là tận dụng ANTLRworks có thể đáng giá, nhưng đối với một số người, chuyển đổi các loại ngữ pháp có thể là một kinh nghiệm rất đau đớn. Nói cách khác: YMMV.


4
thích nó bởi vì nó giải thích lịch sử đằng sau các cơ chế khác nhau khiến mọi người hiểu ngay lập tức
zinking

35

Một vài lợi thế cho ANTLR:

  • có thể xuất trình phân tích cú pháp bằng nhiều ngôn ngữ khác nhau - Java không cần thiết để chạy trình phân tích cú pháp được tạo.
  • GUI tuyệt vời giúp dễ dàng gỡ lỗi ngữ pháp (ví dụ: bạn có thể thấy quyền của AST được tạo trong GUI, không cần thêm công cụ nào)
  • Mã được tạo ra thực sự có thể đọc được bằng con người (đó là một trong những mục tiêu của ANTLR) và thực tế là nó tạo ra các trình phân tích LL chắc chắn giúp ích trong vấn đề này.
  • định nghĩa của các thiết bị đầu cuối cũng không có ngữ cảnh (trái ngược với regex trong (f) lex) - do đó, cho phép, ví dụ, định nghĩa của các thiết bị đầu cuối có chứa dấu ngoặc đơn được đóng đúng

0,02 đô la của tôi


9

Một ưu điểm khác của ANTRL là bạn có thể sử dụng ANTLRWORKS , mặc dù tôi không thể nói rằng đây là một lợi thế nghiêm ngặt, vì có thể có các công cụ tương tự cho các trình tạo khác.


9
  • Bison và Flex dẫn đến dung lượng bộ nhớ nhỏ hơn, nhưng bạn không có IDE đồ họa.
  • antlr sử dụng nhiều bộ nhớ hơn, nhưng bạn có antlrworks, một IDE đồ họa.

Việc sử dụng bộ nhớ Bison / Flex thường là mbyte hoặc hơn. Tương phản với antlr - giả sử nó sử dụng 512 byte bộ nhớ cho mỗi mã thông báo trong tệp bạn muốn phân tích. 4 triệu mã thông báo và bạn hết bộ nhớ ảo trên hệ thống 32 bit.

Nếu tệp mà bạn muốn phân tích cú pháp lớn, antlr có thể hết bộ nhớ, vì vậy nếu bạn chỉ muốn phân tích tệp cấu hình, thì đó sẽ là một giải pháp khả thi. Mặt khác, nếu bạn muốn phân tích một tệp có nhiều dữ liệu, hãy thử Bison.


7
Tôi tò mò. Bạn có thể chỉ đến tài liệu mô tả mức tiêu thụ 512 byte bộ nhớ cho mỗi mã thông báo không? Tôi không nhớ là đã thấy cuộc thảo luận đó. Sự lựa chọn từ khóa Google của tôi cũng không mang lại cho tôi sự hài lòng ...
Don Wakefield

2
Bạn đang nói về dấu chân bộ nhớ của trình tạo trình phân tích cú pháp trong khi tạo trình phân tích cú pháp hay bạn đang nói về dấu chân bộ nhớ của trình phân tích cú pháp được tạo trong khi phân tích cú pháp đầu vào cho ngôn ngữ nguồn? Hàng triệu mã thông báo trong một ngữ pháp sẽ hoàn toàn điên rồ. Bạn nên bị nhốt trong một viện tâm thần nếu bạn nghiêm túc cố gắng bán một ý tưởng như vậy. Đối với các tệp đầu vào cho chính trình phân tích cú pháp, có thể có những trường hợp chúng có số lượng mã thông báo cực lớn, nhưng hầu hết các ngôn ngữ đều là mô-đun, bạn không phân tích toàn bộ đầu vào trong một tệp, các mô-đun riêng lẻ nhỏ hơn.
trijezdci
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.