it-swarm-vi.com

Tôi có nên sử dụng trình tạo trình phân tích cú pháp hay tôi nên cuộn mã lexer và trình phân tích cú pháp tùy chỉnh của riêng mình?

Điều gì cụ thể ưu điểm và nhược điểm của từng cách để làm việc với ngữ pháp ngôn ngữ lập trình?

Tại sao/Khi nào tôi nên tự lăn? Tại sao/Khi nào tôi nên sử dụng máy phát điện?

83
Maniero

Có ba lựa chọn thực sự, cả ba đều thích hợp hơn trong các tình huống khác nhau.

Tùy chọn 1: trình tạo trình phân tích cú pháp hoặc 'bạn cần phân tích một số ngôn ngữ và bạn chỉ muốn làm cho nó hoạt động, chết tiệt'

Giả sử, bạn được yêu cầu xây dựng trình phân tích cú pháp cho một số định dạng dữ liệu cổ NGAY BÂY GIỜ. Hoặc bạn cần trình phân tích cú pháp của bạn để được nhanh chóng. Hoặc bạn cần trình phân tích cú pháp của bạn để có thể dễ dàng duy trì.

Trong những trường hợp này, có lẽ bạn tốt nhất nên sử dụng trình tạo phân tích cú pháp. Bạn không cần phải tìm hiểu chi tiết, bạn không cần phải có nhiều mã phức tạp để hoạt động chính xác, bạn chỉ cần viết ra ngữ pháp mà đầu vào sẽ tuân thủ, viết một số mã xử lý và trình phân tích cú pháp tức thì.

Những lợi thế rất rõ ràng:

  • Thật dễ dàng để viết một đặc tả, đặc biệt nếu định dạng đầu vào không quá lạ (tùy chọn 2 sẽ tốt hơn nếu có).
  • Bạn kết thúc với một phần công việc rất dễ bảo trì dễ hiểu: một định nghĩa ngữ pháp thường chảy tự nhiên hơn nhiều so với mã.
  • Các trình phân tích cú pháp được tạo bởi các trình tạo trình phân tích cú pháp tốt thường nhanh hơn rất nhiều so với mã viết tay. Mã viết tay can nhanh hơn, nhưng chỉ khi bạn biết công cụ của mình - đây là lý do tại sao hầu hết các trình biên dịch được sử dụng rộng rãi đều sử dụng trình phân tích cú pháp đệ quy viết tay.

Có một điều bạn phải cẩn thận với trình tạo phân tích cú pháp: đôi khi có thể từ chối ngữ pháp của bạn. Để biết tổng quan về các loại trình phân tích cú pháp khác nhau và cách chúng có thể cắn bạn, bạn có thể muốn bắt đầu tại đây . Tại đây bạn có thể tìm thấy tổng quan về rất nhiều triển khai và các loại ngữ pháp mà họ chấp nhận.

Tùy chọn 2: trình phân tích cú pháp viết tay hoặc 'bạn muốn xây dựng trình phân tích cú pháp của riêng mình và bạn quan tâm đến việc thân thiện với người dùng'

Trình tạo phân tích cú pháp là Nice, nhưng chúng không thân thiện với người dùng (người dùng cuối, không phải bạn). Bạn thường không thể đưa ra thông báo lỗi tốt, cũng như không thể cung cấp phục hồi lỗi. Có lẽ ngôn ngữ của bạn rất kỳ lạ và các trình phân tích cú pháp từ chối ngữ pháp của bạn hoặc bạn cần kiểm soát nhiều hơn trình tạo cho bạn.

Trong những trường hợp này, sử dụng trình phân tích cú pháp đệ quy gốc viết tay có lẽ là tốt nhất. Mặc dù việc xử lý đúng có thể phức tạp, bạn có toàn quyền kiểm soát trình phân tích cú pháp của mình để bạn có thể thực hiện tất cả các loại công cụ Nice mà bạn không thể làm với trình tạo trình phân tích cú pháp, như thông báo lỗi và thậm chí khôi phục lỗi (thử xóa tất cả dấu chấm phẩy khỏi tệp C # : trình biên dịch C # sẽ khiếu nại, nhưng dù sao cũng sẽ phát hiện ra hầu hết các lỗi khác bất kể sự hiện diện của dấu chấm phẩy).

Các trình phân tích cú pháp viết tay cũng thường hoạt động tốt hơn các trình phân tích cú pháp được tạo ra, giả sử chất lượng của trình phân tích cú pháp là đủ cao. Mặt khác, nếu bạn không quản lý để viết một trình phân tích cú pháp tốt - thường là do (sự kết hợp) thiếu kinh nghiệm, kiến ​​thức hoặc thiết kế - thì hiệu suất thường chậm hơn. Đối với các từ vựng thì ngược lại là đúng: các từ vựng được tạo ra thường sử dụng tra cứu bảng, làm cho chúng nhanh hơn (hầu hết) các văn bản viết tay.

Giáo dục, viết trình phân tích cú pháp của riêng bạn sẽ dạy cho bạn nhiều hơn là sử dụng một trình tạo. Rốt cuộc, bạn phải viết mã ngày càng phức tạp hơn, cộng với việc bạn phải hiểu chính xác cách bạn phân tích một ngôn ngữ. Mặt khác, nếu bạn muốn học cách tạo ngôn ngữ của riêng mình (vì vậy, có kinh nghiệm về thiết kế ngôn ngữ), thì tùy chọn 1 hoặc tùy chọn 3 là thích hợp hơn: nếu bạn đang phát triển một ngôn ngữ, nó có thể sẽ thay đổi rất nhiều, và tùy chọn 1 và 3 cho bạn thời gian dễ dàng hơn với điều đó.

Tùy chọn 3: trình tạo trình phân tích cú pháp viết tay hoặc 'bạn đang cố gắng học hỏi nhiều từ dự án này và bạn sẽ không phiền khi kết thúc với một đoạn mã tiện lợi mà bạn có thể sử dụng lại nhiều'

Đây là con đường tôi hiện đang đi xuống: bạn viết của riêng bạn trình tạo trình phân tích cú pháp. Mặc dù rất không cần thiết, nhưng làm điều này có thể sẽ dạy cho bạn nhiều nhất.

Để cho bạn biết những gì làm một dự án như thế này liên quan đến tôi sẽ cho bạn biết về tiến trình của riêng tôi.

Trình tạo lexer

Tôi đã tạo trình tạo lexer của riêng mình trước. Tôi thường thiết kế phần mềm bắt đầu bằng cách sử dụng mã, vì vậy tôi đã nghĩ về cách tôi muốn có thể sử dụng mã của mình và viết đoạn mã này (nó ở C #):

Lexer<CalculatorToken> calculatorLexer = new Lexer<CalculatorToken>(
    new List<StringTokenPair>()
    { // This is just like a Lex specification:
      //                    regex   token
        new StringTokenPair("\\+",  CalculatorToken.Plus),
        new StringTokenPair("\\*",  CalculatorToken.Times),
        new StringTokenPair("(",    CalculatorToken.LeftParenthesis),
        new StringTokenPair(")",    CalculatorToken.RightParenthesis),
        new StringTokenPair("\\d+", CalculatorToken.Number),
    });

foreach (CalculatorToken token in
             calculatorLexer.GetLexer(new StringReader("15+4*10")))
{ // This will iterate over all tokens in the string.
    Console.WriteLine(token.Value);
}

// Prints:
// 15
// +
// 4
// *
// 10

Các cặp mã thông báo chuỗi đầu vào được chuyển đổi thành cấu trúc đệ quy tương ứng mô tả các biểu thức chính quy mà chúng thể hiện bằng cách sử dụng các ý tưởng của ngăn xếp số học. Điều này sau đó được chuyển đổi thành NFA (automaton hữu hạn hữu hạn), sau đó được chuyển đổi thành DFA (automaton hữu hạn xác định). Sau đó, bạn có thể kết hợp các chuỗi với DFA.

Bằng cách này, bạn sẽ có được một ý tưởng tốt về cách chính xác các từ vựng hoạt động. Ngoài ra, nếu bạn thực hiện đúng cách, kết quả từ trình tạo lexer của bạn có thể nhanh như triển khai chuyên nghiệp. Bạn cũng không mất bất kỳ biểu cảm nào so với tùy chọn 2 và không có nhiều biểu cảm so với tùy chọn 1.

Tôi đã triển khai trình tạo lexer của mình chỉ trong hơn 1600 dòng mã. Mã này làm cho công việc trên, nhưng nó vẫn tạo ra lexer khi bạn khởi động chương trình: Tôi sẽ thêm mã để ghi nó vào đĩa vào một lúc nào đó.

Nếu bạn muốn biết cách viết từ vựng của riêng bạn, này là một nơi tốt để bắt đầu.

Trình tạo trình phân tích cú pháp

Sau đó, bạn viết trình tạo trình phân tích cú pháp của bạn. Tôi đề cập đến ở đây một lần nữa để biết tổng quan về các loại trình phân tích cú pháp khác nhau - như một quy tắc chung, chúng càng có thể phân tích cú pháp, chúng càng chậm.

Tốc độ không phải là vấn đề đối với tôi, tôi đã chọn triển khai trình phân tích cú pháp Earley. Việc triển khai nâng cao của trình phân tích cú pháp Earley đã được hiển thị chậm hơn khoảng hai lần so với các loại trình phân tích cú pháp khác.

Đổi lại với tốc độ đó, bạn có khả năng phân tích cú pháp any loại ngữ pháp, thậm chí mơ hồ. Điều này có nghĩa là bạn không bao giờ phải lo lắng về việc trình phân tích cú pháp của bạn có bất kỳ đệ quy trái nào trong đó hay không, hoặc xung đột giảm ca là gì. Bạn cũng có thể xác định ngữ pháp dễ dàng hơn bằng cách sử dụng các ngữ pháp mơ hồ nếu kết quả là cây phân tích cú pháp nào không quan trọng, chẳng hạn như bạn phân tích 1 + 2 + 3 như (1 + 2) +3 hay 1 + (2 + 3).

Đây là những gì một đoạn mã sử dụng trình tạo trình phân tích cú pháp của tôi có thể trông như sau:

Lexer<CalculatorToken> calculatorLexer = new Lexer<CalculatorToken>(
    new List<StringTokenPair>()
    {
        new StringTokenPair("\\+",  CalculatorToken.Plus),
        new StringTokenPair("\\*",  CalculatorToken.Times),
        new StringTokenPair("(",    CalculatorToken.LeftParenthesis),
        new StringTokenPair(")",    CalculatorToken.RightParenthesis),
        new StringTokenPair("\\d+", CalculatorToken.Number),
    });

Grammar<IntWrapper, CalculatorToken> calculator
    = new Grammar<IntWrapper, CalculatorToken>(calculatorLexer);

// Declaring the nonterminals.
INonTerminal<IntWrapper> expr = calculator.AddNonTerminal<IntWrapper>();
INonTerminal<IntWrapper> term = calculator.AddNonTerminal<IntWrapper>();
INonTerminal<IntWrapper> factor = calculator.AddNonTerminal<IntWrapper>();

// expr will be our head nonterminal.
calculator.SetAsMainNonTerminal(expr);

// expr: term | expr Plus term;
calculator.AddProduction(expr, term.GetDefault());
calculator.AddProduction(expr,
                         expr.GetDefault(),
                         CalculatorToken.Plus.GetDefault(),
                         term.AddCode(
                         (x, r) => { x.Result.Value += r.Value; return x; }
                         ));

// term: factor | term Times factor;
calculator.AddProduction(term, factor.GetDefault());
calculator.AddProduction(term,
                         term.GetDefault(),
                         CalculatorToken.Times.GetDefault(),
                         factor.AddCode
                         (
                         (x, r) => { x.Result.Value *= r.Value; return x; }
                         ));

// factor: LeftParenthesis expr RightParenthesis
//         | Number;
calculator.AddProduction(factor,
                         CalculatorToken.LeftParenthesis.GetDefault(),
                         expr.GetDefault(),
                         CalculatorToken.RightParenthesis.GetDefault());
calculator.AddProduction(factor,
                         CalculatorToken.Number.AddCode
                         (
                         (x, s) => { x.Result = new IntWrapper(int.Parse(s));
                                     return x; }
                         ));

IntWrapper result = calculator.Parse("15+4*10");
// result == 55

(Lưu ý rằng IntWrapper chỉ đơn giản là một Int32, ngoại trừ C # yêu cầu nó phải là một lớp, do đó tôi phải giới thiệu một lớp bao bọc)

Tôi hy vọng bạn thấy rằng đoạn mã trên rất mạnh mẽ: bất kỳ ngữ pháp nào bạn có thể đưa ra đều có thể được phân tích cú pháp. Bạn có thể thêm các đoạn mã tùy ý trong ngữ pháp có khả năng thực hiện nhiều nhiệm vụ. Nếu bạn quản lý để làm cho tất cả điều này hoạt động, bạn có thể sử dụng lại mã kết quả để thực hiện rất nhiều nhiệm vụ rất dễ dàng: chỉ cần tưởng tượng xây dựng một trình thông dịch dòng lệnh bằng cách sử dụng đoạn mã này.

78
Alex ten Brink

Nếu bạn chưa bao giờ, đã từng viết một trình phân tích cú pháp tôi sẽ khuyên bạn nên làm điều đó. Thật thú vị, và bạn học được cách mọi thứ hoạt động, và bạn học cách đánh giá cao nỗ lực mà trình phân tích cú pháp và trình tạo từ vựng giúp bạn không phải làm tiếp theo một trình phân tích cú pháp.

Tôi cũng đề nghị bạn thử đọc http://compilers.iecc.com/crenshaw/ vì nó có thái độ rất thực tế đối với cách thực hiện.

22
user1249

Ưu điểm của việc viết trình phân tích cú pháp gốc đệ quy của riêng bạn là bạn có thể tạo thông báo lỗi chất lượng cao về lỗi cú pháp. Sử dụng trình tạo trình phân tích cú pháp, bạn có thể tạo các lỗi sản xuất và thêm thông báo lỗi tùy chỉnh tại một số điểm nhất định, nhưng trình tạo trình phân tích cú pháp chỉ không phù hợp với sức mạnh của việc kiểm soát hoàn toàn việc phân tích cú pháp.

Một lợi thế khác của việc viết của riêng bạn là dễ dàng phân tích thành một cách trình bày đơn giản hơn mà không có sự tương ứng 1-1 với ngữ pháp của bạn.

Nếu ngữ pháp của bạn đã được sửa và các thông báo lỗi rất quan trọng, hãy xem xét việc tự lăn hoặc ít nhất là sử dụng trình tạo trình phân tích cú pháp cung cấp cho bạn các thông báo lỗi bạn cần. Nếu ngữ pháp của bạn liên tục thay đổi, bạn nên xem xét sử dụng trình tạo phân tích cú pháp thay thế.

Bjarne Stroustrup nói về cách anh ta sử dụng YACC cho lần triển khai C++ đầu tiên (xem Thiết kế và tiến hóa của C++ ). Trong trường hợp đầu tiên, anh ta muốn anh ta viết trình phân tích cú pháp gốc đệ quy của riêng mình!

14
Macneil

Tùy chọn 3: Không (Cuộn trình tạo trình phân tích cú pháp của riêng bạn)

Chỉ vì có lý do để không sử dụng ANTLR , bison , Coco/R , Grammatica , JavaCC , Lemon , Parboiled , SableCC , Quex , vv - điều đó không có nghĩa là bạn nên ngay lập tức cuộn trình phân tích cú pháp + lexer của riêng bạn.

Xác định why tất cả các công cụ này không đủ tốt - tại sao chúng không cho phép bạn đạt được mục tiêu của mình?

Trừ khi bạn chắc chắn rằng những điểm kỳ lạ trong ngữ pháp mà bạn đang xử lý là duy nhất, bạn không nên tạo một trình phân tích cú pháp tùy chỉnh duy nhất + từ vựng cho nó. Thay vào đó, hãy tạo một công cụ sẽ tạo ra những gì bạn muốn, nhưng cũng có thể được sử dụng để đáp ứng các nhu cầu trong tương lai, sau đó phát hành nó dưới dạng Phần mềm miễn phí để ngăn chặn những người khác gặp vấn đề tương tự như bạn.

10
Peter Boughton

Cuộn trình phân tích cú pháp của riêng bạn buộc bạn phải suy nghĩ trực tiếp về sự phức tạp của ngôn ngữ của bạn. Nếu ngôn ngữ khó phân tích, có lẽ nó sẽ khó hiểu.

Có rất nhiều sự quan tâm đến các trình tạo phân tích cú pháp trong những ngày đầu, được thúc đẩy bởi cú pháp ngôn ngữ rất phức tạp (một số người sẽ nói "bị tra tấn"). JOVIAL là một ví dụ đặc biệt tồi tệ: nó yêu cầu hai biểu tượng nhìn vào thời điểm mà mọi thứ khác yêu cầu nhiều nhất là một biểu tượng. Điều này làm cho việc tạo trình phân tích cú pháp cho trình biên dịch JOVIAL trở nên khó khăn hơn mong đợi (vì General Dynamics/Fort Worth Division đã học được cách khó khăn khi họ mua trình biên dịch JOVIAL cho chương trình F-16).

Ngày nay, gốc đệ quy là phương pháp phổ biến, bởi vì nó dễ dàng hơn cho các nhà văn biên dịch. Trình biên dịch gốc đệ quy thưởng mạnh mẽ cho thiết kế ngôn ngữ đơn giản, gọn gàng, trong đó việc viết một trình phân tích cú pháp gốc đệ quy cho một ngôn ngữ đơn giản, gọn gàng hơn là một ngôn ngữ lộn xộn, lộn xộn.

Cuối cùng: Bạn đã cân nhắc việc nhúng ngôn ngữ của mình vào LISP và để một thông dịch viên LISP thực hiện công việc nặng nhọc cho bạn chưa? AutoCAD đã làm điều đó, và thấy nó làm cho cuộc sống của họ dễ dàng hơn rất nhiều. Có khá nhiều trình thông dịch LISP nhẹ ngoài kia, một số có thể nhúng.

8
John R. Strohm

Tôi đã viết một trình phân tích cú pháp cho ứng dụng thương mại một lần và tôi đã sử dụng yacc. Có một nguyên mẫu cạnh tranh trong đó một nhà phát triển đã viết toàn bộ bằng tay trong C++ và nó hoạt động chậm hơn khoảng năm lần.

Đối với lexer cho trình phân tích cú pháp này, tôi đã viết nó hoàn toàn bằng tay. Phải mất - xin lỗi, đã gần 10 năm rồi, vì vậy tôi không nhớ chính xác - khoảng 1000 dòng trong C .

Lý do tại sao tôi viết lexer bằng tay là ngữ pháp đầu vào của trình phân tích cú pháp. Đó là một yêu cầu, một cái gì đó mà việc triển khai trình phân tích cú pháp của tôi phải tuân thủ, trái ngược với thứ tôi thiết kế. (Tất nhiên tôi sẽ thiết kế nó theo cách khác. Và tốt hơn!) Ngữ pháp phụ thuộc hoàn toàn vào ngữ cảnh và thậm chí từ vựng phụ thuộc vào ngữ nghĩa ở một số nơi. Ví dụ, dấu chấm phẩy có thể là một phần của mã thông báo ở một nơi, nhưng dấu phân cách ở một nơi khác - dựa trên cách giải thích ngữ nghĩa của một số phần tử đã được phân tích cú pháp trước đó. Vì vậy, tôi "chôn vùi" những phụ thuộc ngữ nghĩa như vậy trong từ vựng viết tay và điều đó khiến tôi khá đơn giản [~ # ~] bnf [~ # ~] đó là dễ dàng để thực hiện trong yacc.

ĐÃ THÊM để phản hồi lại Macneil: yacc cung cấp một sự trừu tượng hóa rất mạnh mẽ cho phép lập trình viên suy nghĩ về các thiết bị đầu cuối, không phải thiết bị đầu cuối, sản phẩm và những thứ như thế. Ngoài ra, khi triển khai hàm yylex(), nó giúp tôi tập trung vào việc trả lại mã thông báo hiện tại và không lo lắng về những gì trước hoặc sau nó. Lập trình viên C++ làm việc ở cấp độ ký tự, không có lợi ích của sự trừu tượng hóa đó và cuối cùng tạo ra một thuật toán phức tạp hơn và kém hiệu quả hơn. Chúng tôi kết luận rằng tốc độ chậm hơn không liên quan gì đến chính C++ hoặc bất kỳ thư viện nào. Chúng tôi đã đo tốc độ phân tích cú pháp thuần túy với các tệp được tải trong bộ nhớ; nếu chúng tôi gặp sự cố đệm tệp, yacc sẽ không phải là công cụ được chúng tôi lựa chọn để giải quyết.

CSONG MUỐN THÊM: đây không phải là một công thức để viết các trình phân tích cú pháp nói chung, chỉ là một ví dụ về cách nó hoạt động trong một tình huống cụ thể.

6
azheglov

Nó phụ thuộc vào mục tiêu của bạn là gì.

Bạn đang cố gắng học cách trình phân tích cú pháp/trình biên dịch làm việc? Sau đó viết riêng của bạn từ đầu. Đó là cách duy nhất bạn thực sự học để đánh giá cao tất cả những gì họ đang làm. Tôi đã viết một vài tháng qua, và đó là một trải nghiệm thú vị và có giá trị, đặc biệt là 'ah, vì vậy đó là lý do tại sao ngôn ngữ X thực hiện điều này ...'.

Bạn có cần nhanh chóng kết hợp một cái gì đó cho một ứng dụng đúng hạn không? Sau đó, có lẽ sử dụng một công cụ phân tích cú pháp.

Bạn có cần một cái gì đó mà bạn muốn mở rộng trong vòng 10, 20, thậm chí 30 năm tới không? Viết của riêng bạn, và dành thời gian của bạn. Nó sẽ có giá trị nó.

3
GrandmasterB

Điều đó phụ thuộc hoàn toàn vào những gì bạn cần phân tích. Bạn có thể tự lăn nhanh hơn bạn có thể đạt được tốc độ học tập của một người từ chối không? Các công cụ được phân tích cú pháp tĩnh có đủ để bạn không hối hận về quyết định này không? Bạn có thấy việc triển khai hiện tại quá phức tạp không? Nếu vậy, hãy vui vẻ tự lăn, nhưng chỉ khi bạn không tránh khỏi một đường cong học tập.

Gần đây, tôi đã thực sự thích trình phân tích cú pháp chanh , được cho là đơn giản và dễ dàng nhất mà tôi từng sử dụng. Vì mục đích làm cho mọi thứ dễ bảo trì, tôi chỉ sử dụng nó cho hầu hết các nhu cầu. SQLite sử dụng nó cũng như một số dự án đáng chú ý khác.

Nhưng, tôi hoàn toàn không hứng thú với các từ vựng, ngoài ra chúng không cản trở tôi khi tôi cần sử dụng một (do đó, chanh). Bạn có thể, và nếu vậy, tại sao không làm cho một? Tôi có cảm giác bạn sẽ quay lại sử dụng một thứ tồn tại, nhưng hãy gãi ngứa nếu bạn phải :)

3
Tim Post

Bạn đã xem xét phương pháp tiếp cận bàn làm việc ngôn ngữ của Martin Fowlers ? Trích dẫn từ bài báo

Sự thay đổi rõ ràng nhất mà bàn làm việc ngôn ngữ tạo ra cho phương trình là sự dễ dàng tạo DSL bên ngoài. Bạn không còn phải viết một trình phân tích cú pháp. Bạn phải xác định cú pháp trừu tượng - nhưng đó thực sự là một bước mô hình hóa dữ liệu khá đơn giản. Ngoài ra, DSL của bạn có được sức mạnh IDE - mặc dù bạn phải dành một chút thời gian để xác định trình soạn thảo đó. Trình tạo vẫn là việc bạn phải làm và ý nghĩa của tôi là nó không nhiều dễ dàng hơn bao giờ hết. Nhưng sau đó, việc xây dựng một máy phát cho DSL tốt và đơn giản là một trong những phần dễ nhất của bài tập.

Đọc điều đó, tôi sẽ nói rằng những ngày viết trình phân tích cú pháp của riêng bạn đã hết và tốt hơn là sử dụng một trong những thư viện có sẵn. Khi bạn đã thành thạo thư viện thì tất cả các DSL mà bạn tạo trong tương lai đều được hưởng lợi từ kiến ​​thức đó. Ngoài ra, những người khác không phải học cách tiếp cận của bạn để phân tích cú pháp.

Chỉnh sửa để che bình luận (và câu hỏi sửa đổi)

Ưu điểm của việc tự lăn

  1. Bạn sẽ sở hữu trình phân tích cú pháp và có được tất cả những trải nghiệm đáng yêu về suy nghĩ thông qua một loạt các vấn đề phức tạp
  2. Bạn có thể nghĩ ra một điều đặc biệt mà không ai khác nghĩ tới (không chắc nhưng bạn có vẻ là một người thông minh)
  3. Nó sẽ khiến bạn bận rộn với một vấn đề thú vị

Vì vậy, trong ngắn hạn, bạn nên tự lăn lộn khi bạn muốn thực sự hack sâu vào ruột của một vấn đề khó khăn nghiêm trọng mà bạn cảm thấy có động lực mạnh mẽ để làm chủ.

Ưu điểm của việc sử dụng thư viện của người khác

  1. Bạn sẽ tránh phát minh lại bánh xe (một vấn đề phổ biến trong lập trình bạn sẽ đồng ý)
  2. Bạn có thể tập trung vào kết quả cuối cùng (ngôn ngữ mới sáng bóng của bạn) và không phải lo lắng quá nhiều về cách phân tích cú pháp, v.v.
  3. Bạn sẽ thấy ngôn ngữ của mình hoạt động nhanh hơn nhiều (nhưng phần thưởng của bạn sẽ ít hơn vì đó không phải là tất cả của bạn)

Do đó, nếu bạn muốn có kết quả nhanh chóng, hãy sử dụng thư viện của người khác.

Nhìn chung, điều này dẫn đến một sự lựa chọn về mức độ bạn muốn sở hữu vấn đề, và do đó là giải pháp. Nếu bạn muốn tất cả sau đó cuộn của riêng bạn.

3
Gary Rowe

Lợi thế lớn để viết của riêng bạn là bạn sẽ biết cách viết của riêng bạn. Lợi thế lớn khi sử dụng một công cụ như yacc là bạn sẽ biết cách sử dụng công cụ này. Tôi là một fan hâm mộ của treetop cho khám phá ban đầu.

2
philosodad

Tại sao không rẽ nhánh một trình tạo trình phân tích cú pháp nguồn mở và biến nó thành của riêng bạn? Nếu bạn không sử dụng trình tạo trình phân tích cú pháp, mã của bạn sẽ rất khó duy trì, nếu bạn thực hiện thay đổi lớn cú pháp ngôn ngữ của mình.

Trong các trình phân tích cú pháp của mình, tôi đã sử dụng các biểu thức chính quy (ý tôi là kiểu Perl) để mã hóa và sử dụng một số hàm tiện lợi để tăng khả năng đọc mã. Tuy nhiên, mã do trình phân tích cú pháp tạo ra có thể nhanh hơn bằng cách tạo các bảng trạng thái và dài switch-cases, có thể tăng kích thước mã nguồn trừ khi bạn .gitignore họ.

Đây là hai ví dụ về trình phân tích cú pháp tùy chỉnh bằng văn bản của tôi:

https://github.com/SHiNKiROU/DesignScript - một phương ngữ BASIC, vì tôi quá lười để viết lookahead trong ký hiệu mảng, tôi đã hy sinh chất lượng thông báo lỗi https: // github. com/SHiNKiROU/ExprParser - Một máy tính công thức. Lưu ý các thủ thuật siêu lập trình kỳ lạ

1
Ming-Tang

"Tôi có nên sử dụng 'bánh xe' đã thử và thử lại này không?"

0
JBRWilkinson