Trình phân tích cú pháp toán học JavaScript

Phân tích sâu hơn về trạng thái bảo trì của trình phân tích cú pháp toán học-js dựa trên nhịp phiên bản npm đã phát hành, hoạt động của kho lưu trữ và các điểm dữ liệu khác đã xác định rằng việc bảo trì của nó là Không hoạt động

Một tín hiệu bảo trì dự án quan trọng cần xem xét đối với trình phân tích cú pháp toán học-js là nó không thấy bất kỳ phiên bản mới nào được phát hành cho npm trong 12 tháng qua và có thể được coi là một dự án đã ngừng hoặc ít nhận được sự chú ý từ những người bảo trì của nó

Trong tháng trước, chúng tôi không tìm thấy bất kỳ hoạt động yêu cầu kéo nào hoặc thay đổi trạng thái vấn đề đã được phát hiện đối với kho lưu trữ GitHub

Mã thông báo được định nghĩa theo cách tương tự như 1. phiên bản x. Bạn có thể tham khảo tệp thử nghiệm trên các ví dụ về cách thêm mã thông báo. Vì gói này tương thích với TS nên bạn sẽ nhận được tính năng tự động hoàn tất vào ngày

bower install math-expression-evaluator
0

  • Thêm mã thông báo bằng phương thức addToken của đối tượng mexp

     const mexp = new Mexp[]
     mexp.addToken[[token1, token2]] // tokens once added will be preserved in later evaluations
    
  • Thêm mã thông báo bằng phương thức eval của đối tượng mexp

     const mexp = new Mexp[]
     mexp.eval["expression", [token1, token2]] // tokens once added will be preserved in later evaluations
    
  • Thêm mã thông báo bằng cách sử dụng các thành phần của phương thức eval của đối tượng mexp

     const mexp = new Mexp[]
     const answer = mexp.postfixEval[mexp.toPostfix[mexp.lexed["expression", [token1, token2]]]] // tokens once added will be preserved in later evaluations
     console.log[answer]
    
  • Làm thế nào để chạy thử nghiệm

    npm test
    

    Biểu tượng được hỗ trợ

    Giải thích biểu tượng + Toán tử bổ sung, vd. 2+3 kết quả Toán tử trừ 5, vd. 2-3 kết quả -1/ Toán tử chia ví dụ 3/2 kết quả 1. Toán tử nhân 5*, vd. 2*3 kết quả Toán tử 6ModModulus, vd. 3 Mod 2 kết quả 1[Mở ngoặc đơn]Đóng ngoặc đơn&Bitwise AND vd. 3&1 kết quả 1SigmaSummation ví dụ. Kết quả Sigma[1.100,n] 5050PiProduct ví dụ. Kết quả Pi[1,10,n] 3628800nVariable cho Summation hoặc ProductpiMath hằng số pi trả về 3. 14eMath hằng số e trả về 2. Toán tử kết hợp 71C chẳng hạn. 4C2 trả về toán tử 6PPermutation, vd. 4P2 trả về 12. toán tử giai thừa, vd. 4. trả về hàm 24loglogarit với cơ số 10, vd. log 1000 trả về 3lnhàm log tự nhiên với cơ số e, vd. ln 2 trả về. Hàm 3010powpower với hai toán tử pow[2,3] trả về toán tử 8^power, vd. 2^3 trả về 8rootunderroot function root 4 trả về 2sinHàm sin cosHàm cosinetanHàm tiếp tuyếnasinHàm nghịch đảo sinacosHàm nghịch đảo CosineatanHàm nghịch đảoSinhHàm sin hyperboliccoshHàm hyperbolic costanhHàm tiếp tuyến hyperbolic asinhHàm sin hyperbolic nghịch đảoacoshHàm nghịch đảo Hyperbolic TangentHàm hyperbolic tangent

    Đặc trưng

    Hỗ trợ tuyệt vời cho Sigma và Pi

    Đây là một tính năng tuyệt vời của máy tính này mà nó có khả năng đánh giá các biểu thức có chứa Sigma và Pi. Vượt qua

    bower install math-expression-evaluator
    
    1 sẽ có giá trị là 5050 vì n được tính tổng từ 1 đến 100. và Pi[1,15,n] sẽ đánh giá là 1307674368000 khi n được nhân từ 1 đến 15 bằng 15

    Dấu ngoặc đơn bớt biểu thức

    Nếu một biểu thức có thể đọc được bởi con người thì nó có thể được đọc bởi người đánh giá này. Không cần phải bọc mọi chức năng bên trong dấu ngoặc đơn. ví dụ. sin90 sẽ hoạt động hoàn toàn tốt thay vì sin[90]

    Trước đây, tôi đã viết về mã hóa một biểu thức toán học, với Javascript là ngôn ngữ được lựa chọn. Mã thông báo mà tôi đã tạo trong bài viết đó là thành phần đầu tiên trong nhiệm vụ của tôi để hiển thị và giải các biểu thức toán học bằng Javascript hoặc bất kỳ ngôn ngữ nào khác. Trong bài viết này, tôi sẽ hướng dẫn cách xây dựng thành phần tiếp theo. trình phân tích cú pháp

    Công việc của trình phân tích cú pháp là gì? . Nó phân tích biểu thức. [Tât nhiên. ] Được rồi, thực ra, có một câu trả lời hay

    Trình phân tích cú pháp là một thành phần phần mềm lấy dữ liệu đầu vào [thường là văn bản] và xây dựng cấu trúc dữ liệu — thường là một số loại cây phân tích cú pháp, cây cú pháp trừu tượng hoặc cấu trúc phân cấp khác — đưa ra biểu diễn cấu trúc của đầu vào, kiểm tra cú pháp chính xác trong quy trình. Việc phân tích cú pháp có thể được thực hiện trước hoặc sau các bước khác hoặc các bước này có thể được kết hợp thành một bước duy nhất. Trình phân tích cú pháp thường đi trước một bộ phân tích từ vựng riêng biệt, tạo ra các mã thông báo từ chuỗi các ký tự đầu vào

    Vì vậy, về bản chất, đây là những gì chúng tôi đang cố gắng đạt được

    math expression => [parser] => some data structure [we'll get to this in a bit]
    Một cái gì đó như thế này [nguồn. dự án mật mã. com]

    Hãy bỏ qua phía trước một chút. “… Bộ phân tích cú pháp thường đi trước bộ phân tích từ vựng riêng biệt, bộ phân tích này tạo mã thông báo từ chuỗi ký tự đầu vào”. Đây là nói về mã thông báo mà chúng tôi đã xây dựng trước đó. Vì vậy, trình phân tích cú pháp của chúng tôi sẽ không nhận được biểu thức toán học thô, mà là một mảng mã thông báo. Vì vậy, bây giờ, chúng tôi có

    math expression => [tokenizer] => list of tokens => [parser] => some data structure

    Đối với mã thông báo, chúng tôi phải đưa ra thuật toán theo cách thủ công. Đối với trình phân tích cú pháp, chúng tôi sẽ triển khai một thuật toán hiện có, thuật toán Shunting-yard. Hãy nhớ "một số cấu trúc dữ liệu" ở trên?

    Ký hiệu đảo ngược tiếng Ba Lan

    Tôi sẽ bắt đầu với RPN. Một lần nữa từ Wikipedia, RPN là “một ký hiệu toán học trong đó mọi toán tử tuân theo tất cả các toán hạng của nó”. Thay vì có, giả sử, 3+4, RPN sẽ là 3 4 +. Kỳ lạ, tôi biết. Nhưng quy tắc là toán tử phải đứng sau tất cả các toán hạng của nó

    Hãy ghi nhớ quy tắc đó khi chúng ta xem xét một số ví dụ phức tạp hơn. Cũng nên nhớ rằng một toán hạng cho một thao tác có thể là kết quả của một thao tác trước đó]

    Algebraic: 3 - 4                        RPN: 3 4 -
    ______9
     const mexp = new Mexp[]
     mexp.addToken[[token1, token2]] // tokens once added will be preserved in later evaluations
    
    0
     const mexp = new Mexp[]
     mexp.addToken[[token1, token2]] // tokens once added will be preserved in later evaluations
    
    1
     const mexp = new Mexp[]
     mexp.addToken[[token1, token2]] // tokens once added will be preserved in later evaluations
    
    2
     const mexp = new Mexp[]
     mexp.addToken[[token1, token2]] // tokens once added will be preserved in later evaluations
    
    3

    Bởi vì toán tử phải đứng sau toán hạng của nó, RPN còn được gọi là ký hiệu hậu tố và ký hiệu đại số “thông thường” của chúng tôi được gọi là tiền tố

    Làm thế nào để bạn đánh giá một biểu thức trong RPN?

    Đọc tất cả các mã thông báo từ trái sang phải cho đến khi bạn đến Nhà điều hành hoặc Chức năng. Biết rằng Toán tử/Hàm nhận n đối số [ví dụ: cho +, n = 2; cho cos[], n = 1], đánh giá n đối số trước cuối cùng bằng Toán tử/Hàm và thay thế tất cả chúng [Toán tử/ . Tiếp tục như trước, cho đến khi không còn Toán tử/Hàm nào để đọc. Mã thông báo [Chữ hoặc Biến] duy nhất còn lại là câu trả lời của bạn

    [Đây là một thuật toán đơn giản hóa, giả định rằng biểu thức là hợp lệ. Một vài dấu hiệu cho thấy biểu thức không hợp lệ là nếu bạn còn nhiều hơn một mã thông báo ở cuối hoặc nếu mã thông báo cuối cùng còn lại là Toán tử/Hàm. ]

    Vì vậy, đối với những thứ như 5 1 2 + 4 * + 3 −

     const mexp = new Mexp[]
     mexp.addToken[[token1, token2]] // tokens once added will be preserved in later evaluations
    
    4

    Hy vọng bạn đã đạt điểm A trong khóa học cấp tốc nhỏ của tôi về RPN. Bạn đã làm?

    Cây cú pháp trừu tượng

    Định nghĩa của Wikipedia ở đây có thể không quá hữu ích đối với nhiều người trong chúng ta. “một biểu diễn dạng cây của cấu trúc cú pháp trừu tượng của mã nguồn được viết bằng ngôn ngữ lập trình. ” Đối với trường hợp sử dụng này, chúng ta có thể coi AST là cấu trúc dữ liệu đại diện cho cấu trúc toán học của biểu thức. Điều này được nhìn thấy tốt hơn là nói, vì vậy hãy vẽ một sơ đồ sơ bộ. Tôi sẽ bắt đầu với AST cho biểu thức đơn giản 3+4

     const mexp = new Mexp[]
     mexp.addToken[[token1, token2]] // tokens once added will be preserved in later evaluations
    
    5

    Mỗi

    Algebraic: 3 - 4 + 5                    RPN: 3 4 - 5 +
    3 đại diện cho một nút trong cây. Vì vậy, bạn có thể thấy trong nháy mắt rằng hai mã thông báo được kết hợp với nhau bởi toán tử +

    Một biểu thức phức tạp hơn, 5 + [[1 + 2] * 4] − 3

    math expression => [tokenizer] => list of tokens => [parser] => some data structure
    0

    Ah, một cây cú pháp nhỏ đáng yêu. Nó liên kết tất cả các mã thông báo và toán tử một cách hoàn hảo. Bạn có thể thấy rằng việc đánh giá biểu thức này dễ dàng hơn nhiều — chỉ cần đi theo cây

    Vậy, tại sao AST lại hữu ích? . Chẳng hạn, để đánh giá biểu thức trên, trên phần phụ trợ của chúng tôi, chúng tôi có thể làm điều gì đó như thế này

    math expression => [tokenizer] => list of tokens => [parser] => some data structure
    1

    Nói cách khác, đối với mỗi nút toán tử [hoặc chức năng] mà trình đánh giá/trình biên dịch/trình thông dịch gặp phải, nó sẽ kiểm tra xem có bao nhiêu nhánh và sau đó đánh giá kết quả của tất cả các nhánh đó với toán tử

    Được rồi, khóa học về sự cố đã kết thúc, bây giờ hãy quay lại trình phân tích cú pháp của chúng tôi. Trình phân tích cú pháp của chúng tôi sẽ chuyển đổi biểu thức [được mã hóa] thành RPN và sau đó thành AST. Vì vậy, hãy bắt đầu thực hiện nó

    Thuật toán Shunting-yard

    Đây là phiên bản RPN của thuật toán đầy đủ [từ người bạn Wikipedia của chúng tôi] và được sửa đổi để phù hợp với mã thông báo của chúng tôi

    Trong khi có mã thông báo được đọc
    1. Đọc mã thông báo. Hãy gọi nó là
    Algebraic: 3 - 4 + 5                    RPN: 3 4 - 5 +
    4
    2. Nếu
    Algebraic: 3 - 4 + 5                    RPN: 3 4 - 5 +
    4 là Literal hoặc Variable, đẩy nó vào hàng đợi đầu ra
    3. Nếu
    Algebraic: 3 - 4 + 5                    RPN: 3 4 - 5 +
    4 là một Hàm, hãy đẩy nó vào ngăn xếp
    4. Nếu
    Algebraic: 3 - 4 + 5                    RPN: 3 4 - 5 +
    4 là Dấu tách đối số chức năng [dấu phẩy], các toán tử bật khỏi ngăn xếp vào hàng đợi đầu ra cho đến khi mã thông báo ở đầu ngăn xếp là Dấu ngoặc đơn trái
    5. Nếu
    Algebraic: 3 - 4 + 5                    RPN: 3 4 - 5 +
    4 là Toán tử
    a. trong khi có một mã thông báo Toán tử
    Algebraic: 3 - 4 + 5                    RPN: 3 4 - 5 +
    9 ở trên cùng của ngăn xếp toán tử và hoặc là
    Algebraic: 3 - 4 + 5                    RPN: 3 4 - 5 +
    4 là liên kết trái và có mức độ ưu tiên nhỏ hơn hoặc bằng với
    Algebraic: 3 - 4 + 5                    RPN: 3 4 - 5 +
    9 hoặc
    Algebraic: 3 - 4 + 5                    RPN: 3 4 - 5 +
    4 là liên kết phải và có mức độ ưu tiên thấp hơn của
    Algebraic: 3 - 4 + 5                    RPN: 3 4 - 5 +
    9, pop
    b. khi kết thúc lặp đẩy
    Algebraic: 3 - 4 + 5                    RPN: 3 4 - 5 +
    4 vào ngăn toán tử
    6. Nếu mã thông báo là Dấu ngoặc đơn trái, hãy đẩy mã thông báo vào ngăn xếp
    7. Nếu mã thông báo là Dấu ngoặc đơn phải, bật các toán tử ra khỏi ngăn xếp vào hàng đợi đầu ra cho đến khi mã thông báo ở đầu ngăn xếp là một dấu ngoặc đơn bên trái. Sau đó bật dấu ngoặc đơn bên trái từ ngăn xếp, nhưng không vào hàng đợi đầu ra
    8. Nếu mã thông báo ở đầu ngăn xếp là Hàm, hãy đưa nó vào hàng đợi đầu ra
    Khi không còn mã thông báo nào để đọc, hãy đưa bất kỳ mã thông báo Người vận hành nào trên ngăn xếp vào hàng đợi đầu ra
    Lối ra

    [Ghi chú bên lề. trong trường hợp bạn đã đọc bài viết trước, tôi đã cập nhật danh sách các mã thông báo được công nhận để bao gồm Dấu phân cách đối số chức năng, hay còn gọi là dấu phẩy]

    Thuật toán trên giả sử biểu thức là hợp lệ. Tôi đã làm theo cách này để nó dễ hiểu trong ngữ cảnh của một bài báo. Bạn có thể xem thuật toán đầy đủ trên Wikipedia

    Bạn sẽ quan sát một vài điều

    • Chúng ta cần hai cấu trúc dữ liệu. một ngăn xếp để chứa các hàm và toán tử, và một hàng đợi cho đầu ra. Nếu bạn chưa quen với hai cấu trúc dữ liệu này, thì đây là kiến ​​thức cơ bản dành cho bạn. nếu bạn muốn truy xuất một giá trị từ ngăn xếp, bạn bắt đầu với giá trị cuối cùng bạn đưa vào, trong khi đối với hàng đợi, bạn bắt đầu với giá trị đầu tiên bạn đưa vào
    math expression => [tokenizer] => list of tokens => [parser] => some data structure
    2
    • Chúng ta cần biết tính kết hợp của các toán tử. Tính kết hợp đơn giản có nghĩa là một biểu thức chứa một số thao tác cùng loại được nhóm theo thứ tự nào mà không có dấu ngoặc đơn. Chẳng hạn, 2 + 3 + 4 được đánh giá theo quy tắc từ trái sang phải [2+ 3 = 5, sau đó 5 + 4 = 9], do đó + có tính kết hợp trái. So sánh với 2^3^4, được đánh giá là 2^81, không phải 8^4. Do đó ^ có tính kết hợp đúng. Chúng tôi sẽ đóng gói các liên kết của các toán tử gặp phải trong Javascriptobject
    math expression => [tokenizer] => list of tokens => [parser] => some data structure
    3
    • Chúng ta cũng cần biết thứ tự ưu tiên của các toán tử. Quyền ưu tiên là một loại xếp hạng được gán cho các toán tử, vì vậy chúng ta có thể biết thứ tự chúng sẽ được đánh giá nếu chúng xuất hiện trong cùng một biểu thức. Các toán tử có mức độ ưu tiên cao hơn được đánh giá trước. Chẳng hạn, * có mức ưu tiên cao hơn +, vì vậy 2 + 3 * 4 được đánh giá là 2 + 12 chứ không phải 5 * 4, trừ khi sử dụng dấu ngoặc đơn. + và – có cùng mức độ ưu tiên, vì vậy 3 + 5 – 2 có thể được đánh giá là 8–2 hoặc 3+3. Một lần nữa, chúng ta sẽ gói toán tử ưu tiên trong một đối tượng
    math expression => [tokenizer] => list of tokens => [parser] => some data structure
    4

    Bây giờ, hãy cập nhật lớp

     const mexp = new Mexp[]
     mexp.addToken[[token1, token2]] // tokens once added will be preserved in later evaluations
    
    06 của chúng ta để chúng ta có thể dễ dàng truy cập quyền ưu tiên và tính kết hợp thông qua các phương thức

    math expression => [tokenizer] => list of tokens => [parser] => some data structure
    5
    • Chúng tôi cần một phương thức cho phép chúng tôi xem nhanh ngăn xếp [để kiểm tra phần tử ở trên cùng mà không cần xóa nó] và một phương thức cho phép chúng tôi bật ra khỏi ngăn xếp [lấy và xóa mục ở trên cùng]. May mắn thay, mảng Javascript đã có phương thức
       const mexp = new Mexp[]
       mexp.addToken[[token1, token2]] // tokens once added will be preserved in later evaluations
      
      07, vì vậy tất cả những gì chúng ta cần làm là triển khai phương thức
       const mexp = new Mexp[]
       mexp.addToken[[token1, token2]] // tokens once added will be preserved in later evaluations
      
      08. [Hãy nhớ rằng, đối với ngăn xếp, phần tử ở trên cùng là phần tử chúng ta đã thêm lần trước. ]
    math expression => [tokenizer] => list of tokens => [parser] => some data structure
    6

    Vì vậy, đây là những gì chúng ta có

    math expression => [tokenizer] => list of tokens => [parser] => some data structure
    7
    math expression => [tokenizer] => list of tokens => [parser] => some data structure
    8
    math expression => [tokenizer] => list of tokens => [parser] => some data structure
    9
    math expression => [tokenizer] => list of tokens => [parser] => some data structure
    3
    math expression => [tokenizer] => list of tokens => [parser] => some data structure
    4
    math expression => [tokenizer] => list of tokens => [parser] => some data structure
    5
    Algebraic: 3 - 4                        RPN: 3 4 -
    3
    Algebraic: 3 - 4                        RPN: 3 4 -
    4
    Algebraic: 3 - 4                        RPN: 3 4 -
    5

    Tôi sẽ không đi sâu vào việc triển khai thuật toán nên tôi không làm phiền bạn. Đó là một nhiệm vụ khá đơn giản, thực tế là dịch từng từ của thuật toán sang mã, vì vậy, vào cuối ngày, đây là những gì chúng tôi có

    Hàm

     const mexp = new Mexp[]
     mexp.addToken[[token1, token2]] // tokens once added will be preserved in later evaluations
    
    09 chỉ định dạng danh sách mã thông báo RPN của chúng tôi ở định dạng có thể đọc được

    Và chúng ta có thể kiểm tra trình phân tích cú pháp infix-to-postfix của mình

    Algebraic: 3 - 4                        RPN: 3 4 -
    6

    đầu ra

    Algebraic: 3 - 4                        RPN: 3 4 -
    7

    RPN

    Đã đến lúc trồng cây

    Bây giờ, hãy sửa đổi trình phân tích cú pháp của chúng ta để nó trả về AST

    Để tạo AST thay vì RPN, chúng tôi sẽ cần thực hiện một số sửa đổi

    • Chúng tôi sẽ tạo một đối tượng để đại diện cho một nút trong AST của chúng tôi. Mỗi nút có một giá trị và hai nhánh [có thể là
       const mexp = new Mexp[]
       mexp.addToken[[token1, token2]] // tokens once added will be preserved in later evaluations
      
      10]
    Algebraic: 3 - 4                        RPN: 3 4 -
    8
    • Điều thứ hai chúng ta sẽ làm là thay đổi cấu trúc dữ liệu đầu ra thành ngăn xếp. Mặc dù mã thực tế cho việc này chỉ là thay đổi dòng
       const mexp = new Mexp[]
       mexp.addToken[[token1, token2]] // tokens once added will be preserved in later evaluations
      
      11 thành
       const mexp = new Mexp[]
       mexp.addToken[[token1, token2]] // tokens once added will be preserved in later evaluations
      
      12 [vì nó vẫn là một mảng], thay đổi chính nằm ở cách chúng ta hiểu và xử lý mảng này

    Bây giờ, thuật toán infix-to-AST của chúng ta sẽ chạy như thế nào?

    1. Thay vì đẩy mã thông báo Nghĩa đen hoặc Biến đổi lên
       const mexp = new Mexp[]
       mexp.addToken[[token1, token2]] // tokens once added will be preserved in later evaluations
      
      13 của chúng tôi, chúng tôi đẩy một nút mới có giá trị là mã thông báo và có các nhánh là
       const mexp = new Mexp[]
       mexp.addToken[[token1, token2]] // tokens once added will be preserved in later evaluations
      
      10 lên
       const mexp = new Mexp[]
       mexp.addToken[[token1, token2]] // tokens once added will be preserved in later evaluations
      
      15 của chúng tôi
    2. Thay vì bật mã thông báo Toán tử/Hàm từ
       const mexp = new Mexp[]
       mexp.addToken[[token1, token2]] // tokens once added will be preserved in later evaluations
      
      16 , chúng tôi thay thế hai nút trên cùng trên
       const mexp = new Mexp[]
       mexp.addToken[[token1, token2]] // tokens once added will be preserved in later evaluations
      
      15 bằng một nút duy nhất có giá trị là mã thông báo và có hai nút đó làm nhánh của nó. Hãy tạo một hàm thực hiện điều đó
    Algebraic: 3 - 4                        RPN: 3 4 -
    9

    3. Trình phân tích cú pháp của chúng tôi bây giờ sẽ trả về một nút duy nhất, nút ở đầu AST của chúng tôi. Hai nhánh của nó sẽ chứa hai nút con, các nhánh của chúng sẽ chứa các nút con của chúng, v.v., theo cách đệ quy. Chẳng hạn, đối với một biểu thức như 3 + 4 * 2 / [ 1–5 ] ^ 2 ^ 3, chúng ta mong muốn cấu trúc của nút đầu ra sẽ như thế này [ở dạng nằm ngang]

    Algebraic: 3 - 4 + 5                    RPN: 3 4 - 5 +
    0

    Trong sơ đồ trên, dấu => đại diện cho các nhánh của nút [nút trên cùng là nhánh trái, nút dưới cùng là nhánh phải]. Mỗi nút có hai nhánh và các nút ở cuối cây có hướng của chúng là

     const mexp = new Mexp[]
     mexp.addToken[[token1, token2]] // tokens once added will be preserved in later evaluations
    
    18ull

    Vì vậy, nếu chúng ta đặt tất cả những thứ này lại với nhau, đây là đoạn mã chúng ta nghĩ ra

    Và nếu chúng tôi demo nó

    Algebraic: 3 - 4 + 5                    RPN: 3 4 - 5 +
    1
    Algebraic: 3 - 4 + 5                    RPN: 3 4 - 5 +
    2

    Và kết quả

    Ôi cái cây đẹp quá

    Dần dần, nhưng chắc chắn, chúng ta đang tiến gần hơn đến việc hiểu điều gì khiến trình biên dịch và trình thông dịch đánh dấu. Phải thừa nhận rằng hoạt động của các ngôn ngữ lập trình hiện đại và bộ công cụ của chúng phức tạp hơn nhiều so với những gì chúng ta đã xem xét cho đến nay, nhưng tôi hy vọng đây là phần giới thiệu dễ hiểu về chúng. Như một số người đã chỉ ra, các công cụ tồn tại để tự động tạo mã thông báo và trình phân tích cú pháp, nhưng thật tuyệt khi biết một thứ thực sự hoạt động như thế nào

    Các khái niệm chúng tôi đề cập trong bài viết này và trước đó là những chủ đề rất thú vị trong lĩnh vực khoa học máy tính và lý thuyết ngôn ngữ. Tôi vẫn còn nhiều điều cần tìm hiểu về chúng và tôi khuyến khích bạn tiếp tục và nghiên cứu chúng nếu bạn quan tâm. Và gửi cho tôi một dòng để cho tôi biết về sự tiến bộ của bạn. Hòa bình

    QUẢNG CÁO

    QUẢNG CÁO

    QUẢNG CÁO

    QUẢNG CÁO

    QUẢNG CÁO

    QUẢNG CÁO

    QUẢNG CÁO

    QUẢNG CÁO

    QUẢNG CÁO

    QUẢNG CÁO

    QUẢNG CÁO

    QUẢNG CÁO

    Nếu bài viết này hữu ích, hãy tweet nó

    Học cách viết mã miễn phí. Chương trình giảng dạy mã nguồn mở của freeCodeCamp đã giúp hơn 40.000 người có được việc làm với tư cách là nhà phát triển. Bắt đầu

    Làm cách nào để phân tích biểu thức toán học JavaScript?

    Các biểu thức có thể được phân tích cú pháp và đánh giá theo nhiều cách khác nhau. .
    đánh giá [expr [, phạm vi]]
    biên dịch [expr]
    phân tích cú pháp [expr]
    Bằng cách tạo một trình phân tích cú pháp, toán học. parser[] , chứa một phương thức đánh giá và giữ một phạm vi với các biến được gán trong bộ nhớ

    JavaScript có thư viện toán học không?

    Toán. js là một thư viện toán học phong phú dành cho JavaScript và Node.

    Làm cách nào để tính toán một biểu thức toán học được lưu dưới dạng chuỗi trong Java?

    Để đánh giá biểu thức toán học trong Chuỗi, hãy sử dụng Nashorn JavaScript trong Java i. e. viết kịch bản . Nashorn gọi tính năng động, được giới thiệu trong Java 7 để cải thiện hiệu suất.

    Biểu thức JavaScript là gì?

    Biểu thức của JavaScript là một tập hợp hợp lệ gồm các chữ, biến, toán tử và biểu thức đánh giá một giá trị duy nhất là một biểu thức . Giá trị đơn này có thể là một số, một chuỗi hoặc một giá trị logic tùy thuộc vào biểu thức. Ví dụ. Javascript.

    Chủ Đề