1. Trang chủ
  2. » Luận Văn - Báo Cáo

Tìm hiểu về ngôn ngữ lập trình ERLANG

64 3,7K 29

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 64
Dung lượng 743 KB

Nội dung

Erlang cũng là một ngôn ngữ cấp cao, được ra đời nhằm mục đích xây dựng những ứng dụng chạy tốt bằng cách song song hóa các yêu cầu tính toán, hỗ trợ lập trình hàm. Một đặc điểm quan trọng nhất của Erlang đó là đây là ngôn ngữ xây dựng theo hướng lập trình tương tranh (Concurrency – Oriented), một hướng khá mới, tiểu luận của chúng em với mục đích tìm hiểu ngôn ngữ lập trình Erlang với các đặc trưng chính của ngôn ngữ và làm rõ cách xây dựng chương trình theo hướng lập trình tương tranh của Erlang.

Tìm hiểu về ngôn ngữ lập trình Erlang TIỂU LUẬN MÔN HỌC Đề tài : Tìm hiểu về ngôn ngữ lập trình ERLANG. [Type text] 1 Tìm hiểu về ngôn ngữ lập trình Erlang LỜI NÓI ĐẦU 3 ERLANG VÀ HỆ THỐNG HỖ TRỢ LẬP TRÌNH VỚI ERLANG 4 HỆ THỐNG TỪ VỰNG CỦA ERLANG 11 NGỮ NGHĨA CƠ BẢN CỦA ERLANG 12 ĐIỀU KHIỂN LUỒNG TRONG ERLANG 21 MÔI TRƯỜNG THỰC THI CỦA ERLANG 44 KẾT LUẬN 64 [Type text] 2 Tìm hiểu về ngôn ngữ lập trình Erlang LỜI NÓI ĐẦU Ngôn ngữ lập trình rất quan trọng trong việc xây dựng nên những ứng dụng chạy trên máy tính điện tử, những ngôn ngữ lập trình cấp cao hiện nay đều hỗ trợ những phương pháp lập trình mới giúp cho lập trình viên đơn giản hơn trong việc xây dựng chương trình. Nhưng không chỉ dừng lại ở đó các ngôn ngữ lập trình cũng ngày càng phát triển, rất nhiều các ngôn ngữ lập trình mới được ra đời, với nhiều đặc trưng mới phù hợp hơn với các ứng dụng cụ thể, hỗ trợ những paradigm lập trình khác như parallel, object – oriented,… Erlang cũng là một ngôn ngữ cấp cao, được ra đời nhằm mục đích xây dựng những ứng dụng chạy tốt bằng cách song song hóa các yêu cầu tính toán, hỗ trợ lập trình hàm. Một đặc điểm quan trọng nhất của Erlang đó là đây là ngôn ngữ xây dựng theo hướng lập trình tương tranh (Concurrency – Oriented), một hướng khá mới, tiểu luận của chúng em với mục đích tìm hiểu ngôn ngữ lập trình Erlang với các đặc trưng chính của ngôn ngữ và làm rõ cách xây dựng chương trình theo hướng lập trình tương tranh của Erlang. [Type text] 3 Tìm hiểu về ngôn ngữ lập trình Erlang ERLANG VÀ HỆ THỐNG HỖ TRỢ LẬP TRÌNH VỚI ERLANG A. Giới thiệu chung Erlang là một ngôn ngữ lập trình nhằm mục đích lập trình tương tranh cho phép thích ứng trên nhiều nền tảng khác nhau (« run foreve »). Với Erlang, sự song song hóa chỉ phụ thuộc vào ngôn ngữ lập trình chứ không phụ thuộc vào hệ điều hành. Erlang thực hiện cấu trúc chương trình thành các tiến trình tương tranh (concurrent process), từ đó khiến cho việc lập trình song song trở nên dễ dàng bằng cách thông qua các thông điệp được gửi qua lại giữa các tiến trình tương tranh này. Các tiến trình tương tranh này chạy song song nhưng không dựa trên một quá trình chia sẻ bộ nhớ vì vậy không gây ra hiện tượng đợi lẫn nhau giữa các tiến trình.Các tiến trình tương tranh này nhỏ và nhẹ vì vậy mỗi chương trình bao gốm một số lượng lớn các tiến trình tương tranh (lên đến hàng trăm, hàng nghìn) có thể được thực thi trên một bộ xử lý, một bộ xử lý đa lõi, hoặc trên một mạng các bộ xử lý khác nhau. Có 5 lý do mà tác giả của ngôn ngữ khuyên chúng ta nên biết về nó : Chương trình sẽ chạy nhanh hơn khi được thực thi trên một máy tính đa lõi. Khả năng xây dựng ứng dụng có chịu lỗi tốt, chúng có thể được chỉnh sửa mà không cần phải dừng ứng dụng lại. Ngôn ngữ sử dụng paradigm lập trình hàm (functional programming). Đây là một ngôn ngữ được kiểm nghiệm thực tế trong hệ thống sản xuất công nghiệp quy mô lớn.,có các thư viện khổng lồ, và cộng đồng sử dụng rất lớn. Các ứng dụng được viết lượng lượng dòng lệnh không quá nhiều. B. Lịch sử của Erlang Erlang được phát triển tại phòng thí nghiệm Ericsson Computer Science Laboratory vào những năm 1986. Erlang được thiết kế cho việc lập trình tương tranh, một chương trình trong erlang được tạo thành bởi hàng nghìn, hàng vạn các tiến trình, các tiến trình này không chia sẻ bộ nhớ và giao tiếp với nhau qua thông qua các message. Erlang có cơ chế cho phép chương trình có thể thay đổi code ngay khi chúng đang được thực thi, ta gọi [Type text] 4 Tìm hiểu về ngôn ngữ lập trình Erlang đó là cơ chế “on the fly”, chính nhờ cơ chế này ta có thể xây dựng các phần mềm cho các hệ thống non-stop. 1. Giai đoạn 1985-1988 : Sự ra đời của Erlang: Vào những năm 1986, Joe Armstrong dự định phát triển một trịnh biên dịch cho phép lập trình các ứng dụng trên điện thoại một cách hiệu quả. Như chúng ta đã biết, các ứng dụng trên điện thoại có yêu cầu về khả năng tương tranh cao: một thao tác switch phải xử lý hàng trăm thậm chí hàng nghìn các giao dịch. Trong quá trình phát triển, ông bị ảnh hưởng khá nhiều bởi cấu trúc cú pháp của ngôn ngữ Prolog. Trình biên dịch của ông không những hỗ trợ cho nhiều process cũng lúc mà còn có cơ chế trao đổi thông điệp giữa các process, cơ chế bắt lỗi … Cùng với Robert Virding, ông đã nghiên cứu và phát triển ra một ngôn ngữ lập trình, đồng thời phát triển các nguyên lý cho ngôn ngữ này, ngày này chúng ta gọi ngôn ngữ này là Erlang và nguyên lý mà hai người phát triển là “Concurrency-Oriented Programming”. Như vậy Erlang là một ngôn ngữ lai giữa ngôn ngữ lập trình tương tranh và ngôn ngữ lập trình hàm. Hnh 1. Cấu trúc của ngôn ngữ Erlang Vào những năm 1987, Erlang lần đầu tiên được sử dụng để thực hiện các ứng dụng thực tế, erlang được sử dụng để tạo ra một kiến trúc phần mềm mới mang tên là ACS3 được thiết kế cho lập trình các dịch vụ điện thoại trên Ericsson MD110 PABX4, và dự án mang tên ACS/Dunder đã được triển khai, dựa trên ngôn ngữ erlang để xây dựng kiến trúc ACS3. Chính nhờ dự án này, ngôn ngứ erlang được phát triển một cách nhanh chóng, erlang liên tục được cập nhật thêm các tính năng mới, và được áp dụng ngay vào trong thực tế, những tính năng phù hợp sẽ được giữ lại, còn không chúng sẽ được bỏ đi. Hầu hết các thay đổi của Erlang đều không được lưu lại, bảng dưới đây là một trong những mẫu câu lệnh hiếm hoi của erlang trong những ngày đầu phát triển [Type text] 5 Tìm hiểu về ngôn ngữ lập trình Erlang Hnh 2. Các mẫu câu lệnh của Erlang trong những ngày đầu Đến cuối năm 1988, hầu hết mọi ý tưởng trong erlang đã định hình: Bufered message reception: đây là một trong những ý tưởng được thiết kế đầu tiên trong erlang, cú pháp gửi nhận tin nhắn được thực hiện theo mẫu sau : Receive Patten1 -> Action1; Patten2 -> Action2; …; End Error handling: xử lý lỗi trong erlang khác rất nhiều so với xử lý lỗi trong những ngôn ngữ lập trình thông thường, cơ chế xử lý lỗi trong erlang được thiết kế để xây dựng lên một hệ thống chịu lỗi, chúng ta không thể xây dựng một hệ thống chịu lỗi với một máy tính, điều kiện tiên quyết để xây dựng một hệ thống chịu lỗi là hệ thống phải có hai máy tính trở lên, quá trình phát hiện lỗi và phục hồi sẽ được thực hiện trên máy còn lại bởi vì trong trường hợp xấu nhất, máy tính bị lỗi sẽ bị treo và không thể tính toán được nữa dẫn đến không thể phục hồi. Trong erlang, mọi thiết bị phần cứng được coi như một đối tượng, và muốn khi muốn tương tác đến phần cứng thì phải thông qua việc gửi tin nhắn. Điều này khiến cho mọi việc trở lên dễ dàng trong erlang vì tất cả đều được quy về việc xử lý các process, và việc trao đổi tin nhắn giữa các process là đồng nhất chứ không [Type text] 6 Tìm hiểu về ngôn ngữ lập trình Erlang phân biết xem tin nhắn nào là tin nhắn gửi đến thiết bị phần cứng, tin nhắn nào là tin nhắn giữa các process với nhau. Links: links trong erlang dùng để kiểm soát đường truyền lỗi khi xảy ra lỗi giữa các process. Mô hình xử lý lỗi trong erlang như sau: khi một process trong erlang “chết”, sẽ có một số các process đóng vai trò “quan sát viên”, chúng theo dõi cái chết của process đó và sửa những lỗi gây ra cái chết của process kia, tuy nhiên vậy thi process nào trong hệ thống sẽ được đóng vai trò làm “quan sát viên” trong số hàng trăm, hàng nghìn process trong một chương trình của erlang. Chính nhờ links trong erlang mà chúng ta có thể tạo ra một tập các process được liên kết với nhau, và khi một process thông thường chết thi các process liên kết với nó sẽ chết theo, tuy nhiên trong số chúng sẽ có những process được gán làm process hệ thống, khi các process thông thường chết, chúng sẽ có nhiệm vụ khắc phục lỗi. Ý tưởng này do Mike Williams đề xuất. Buffers: như ta đã biết các process trong erlang giao tiếp với nhau thông qua việc gửi thông điệp đến nhau, mỗi một process đều có một “mailbox” để chứa các thông điệp. Khi một thông điệp được gửi đến nó được đưa vào mailbox, và process sẽ lên kế hoạch để thực hiện nó. Nếu process thực hiện đối sánh mẫu thông điệp trong mailbox, nếu thành công thông điệp sẽ được xóa khỏi mailbox và dữ liệu từ thông điệp sẽ được đưa vào chương trình, nếu không thông điệp sẽ được đưa vào một hàng đợi. Khi bất cứ một thông điệp nào được process xử lý tiếp theo, thì những thông điệp được lưu trong hàng đợi sẽ được đưa lại vào mailbox. 2. Giai đoạn 1989-1997 Trong khoảng thời gian 8 năm này chính là giai đoạn phát triển chính của Erlang, từ thời gian ban đầu chỉ có hai người phát triển, đến giai đoạn này đã có hàng trăm người nghiên cứu và sử dụng erlang. Kết quả của dự án ACS/Dunder: vào tháng 12 năm 1989, báo cáo cuối cùng của dự án ACS/Dunder được đưa ra, đã có khoảng 25 tính năng của điện thoại đã được thực hiện thành công, các tính năng này đại diện cho khoảng một phần mười chức năng của MD110. Báo cáo cũng chỉ ra rằng, Erlang quá chậm để phát triển sản phẩm, để có thể tạo ra các sản phẩm thực tế thì erlang cần phải nhanh hơn 40 lần so với hiện tại, tuy nhiên Ericsson vẫn quyết định xây dựng một sản phẩm gọi là “Mobility Server” dựa trên kiến trúc ACS/Dunder. [Type text] 7 Tìm hiểu về ngôn ngữ lập trình Erlang Mở rộng ra thế giới: năm 1989 cũng là lần đầu tiên Erlang có cơ hội được giới thiệu ra ngoài thế giới thông qua hội nghị SETSS tại Bournemouth. Chính nhờ hội nghị này, mà các tác giả đã được mởi đến Bellcore để nói về Erlang. C. Hệ thống hỗ trợ lập trình Erlang Hệ thống hộ trợ lập trình của Erlang (trình dịch và các thư viện liên quan) được cung cấp miễn phí tại trang web http://www.erlang.org/download.html Tại đây ta có thể chọn nền hệ điều hành của máy tính thực thi là Linux hay Window. Ở đây để tiện cho việc cài đặt và thực thi chương trình em chọn Window. Ngoài ra chúng ta cần lưu ý đến CEAN (The Comprehensive Erlang Archive Network) đây là sự tổng hợp tất cả các ứng dụng quan trọng của Erlang vào một bộ cài đặt duy nhất, điều này giúp cho ta có thể khai thác được một lượng lớn các gói chương trình được viết bằng Erlang. Để có thể sử dụng CEAN, ta truy cập vào đường dẫn http://cean.process-one.net/download/ Việc thực hiện cài đặt chương trình khá đơn giản, sau khi cài đặt xong chương trình ta có thể thấy có hai chương trình thực thi phục vụ cho việc lập trình được gọi là shell trong thư mục .\erl5.7.3\bin đó là: erl.exe đây là shell để chạy trên dòng lệnh command line của window để shell này trước hết ta phải chuyển đến thư mục .\erl5.7.3\bin sau đó thực hiện lệnh erl werl.exe đây là shell để chạy thông qua cứa sổ của window khi nháy kép vào file chạy ta sẽ thấy xuất hiện cửa sổ ứng dụng của shell Dưới đây là shell chạy qua cửa sổ và dòng lệnh chạy thử: [Type text] 8 Tìm hiểu về ngôn ngữ lập trình Erlang Hnh 3. Shell cửa sổ của Erlang và lệnh tính biểu thức 2 * (3 + 4) Từ hình trên ta có thể nhận ra một số thông tin về version của Erlang cũng như version của Eshell. Shell được thực hiện với dấu nhắc 1>. Để thực hiện biểu thức đã cho ta gõ trực tiếp biểu thức sau dấu nhắc của hệ thống. Một lỗi khá gặp đối với người mới lập trình Erlang đó là dấu “.” cuối cùng sau biểu thức. Dấu chấm này đánh dấu kết thúc một dòng lệnh để chuyển sang lệnh kế tiếp (dấu nhắc hệ thống chuyển thành 2>), nếu thiếu dấu chấm này câu lệnh sẽ không được thực hiện và nếu ta ấn ENTER dấu nhắc của hệ thống vẫn là 1> mà không đưa ra được kết quả của biểu thức. 1. Viết code bằng file – module Để tiện cho quá trình lập trình cũng nhưng thêm các tham số cho quá trình biên dịch Erlang hỗ trợ xây dựng các Module. Modules: là đơn vị cơ bản trong Erlang, toàn bộ các functions mà chúng ta viết được chứa trong modules, các modules được lưu trong các file có phần mở rộng .erl. Modules cần được biên dịch trước khi chạy. Một file modules đã được biên dịch sẽ có phần mở rộng là .beam. Xét ví dụ sau: 1>Rectangle = {rectangle, 10, 5}. {rectangle, 10, 5}. [Type text] 9 Tìm hiểu về ngôn ngữ lập trình Erlang 2>Circle = {circle, 2.4}. {circle,2.40000} 3>{rectangle, Width, Ht} = Rectangle. {rectangle,10,5} 4>Width. 10 5>Ht. 5 6>{circle, R} = Circle. {circle,2.40000} 7>R. 2.40000 Ta khởi tạo hai tuple đại diện cho hình chữ nhật với các kích thước là 10 và 5, và hình tròn với bán kính là 2.4. Bây giờ ta sẽ tạo ra một function với tên gọi là area dùng để tính chu vi của hình chữ nhật và hình tròn. Chúng ta sẽ để function này trong module mang tên là geometry và được lưu trong file geometry.erl : -module(geometry). -export([area/1]). area({rectangle, Width, Ht}) -> Width * Ht; area({circle, R}) -> 3.14159 * R * R. Như vậy, ta thấy rằng phần code của function area bao gồm hai mệnh đề được cách nhau bằng dẫu “ ; “ và mệnh đề cuối cùng kết thúc bằng dấu chấm. mỗi mệnh đề có phần đầu và phần thân, phần đầu bao gồm tên function và đi theo nó là pattern (trong ngoặc đơn), phần thân bao gồm các chuỗi các biểu thức sẽ được tính toán nếu các thông số ở pattern phù hợp. Để có thể chạy được chương trình trên ta cần biên dịch nó: 1>c(geometry). {ok,geometry} 2>geometry:area({rectangle, 10, 5}). 50 3> geometry:area({circle, 1.4}). 6.15752 Ở câu lệnh thứ 1 c(geometry) dùng để biên dịch mã code trong file geometry.erl, trình biên dịch trả lại kết quả thành công {ok, geometry}, ở câu lệnh thứ 2 và 3 ta gọi functiong trong module geometry. Khi ta gọi câu lệnh geometry:area({rectangle, 10, 5}), thì việc đầu tiên đó là gán giá trị Width = 10 và Ht = 5, sau đó phần code sau dấu -> được thực hiện đó là lấy Width*Ht. [Type text] 10 [...]...Tỡm hiu v ngụn ng lp trỡnh Erlang H THNG T VNG CA ERLANG D H thng ký t ca ngụn ng Erlang Trong Erlang h thng ký t rt a dng Erlang cú th nhn c khỏ nhiu ký t (tt c ký t ca bng ISO-8859-1 (Latin-1) Cỏc ký t c phõn loi nh di bng sau: Mó c s 8 200 - 237 240 - 277 300 - 326 327 330... ta cú th thc hin nh sau: 8> X2#todo.text "Fix errata in book" 5 List v hng xõu trong Erlang List l kiu d liu tp hp ca ngụn ng Erlang, cng ging trong C, list trong erlang cng dựng lit kờ cỏc bin, kiu d liu tp hp ny cú k th t ca cỏc phn t Kiu d liu ny cú th c khai bỏo nh sau : [Term1, ,TermN] Nh trờn ta thy List trong Erlang c khi to trong cỏc du ngoc vuụng [], cỏc phn t c cỏch nhau bng du , thnh phn... s byte trong mt binary: 1> 5 size() IU ERLANG KHIN LUNG TRONG J Biu thc (Expression) Trong phn ny, chỳng ta s tỡm hiu tt cỏc cỏc loi biu thc uc s dng trong Erlang Chng trỡnh bng Erlang cho phộp chỳng ta s dng cỏc macro v biu thc theo kiu bn ghi Tuy nhiờn, nhng biu thc ny c m rng trong sut lỳc biờn dch, v nú khụng thc s ỳng l biu thc Erlang 1 Biu din biu thc: Tt c cỏc biu thc con c biu... Y} = {1, 2} [Type text] 13 Tỡm hiu v ngụn ng lp trỡnh Erlang ** exception error: no match of right hand side value {1,2} 5> {X, Y} = {2, 3} {2,3} 6> Y 3 Trong khi thc hin Shell ta cú th dựng lờnh f() cho phộp shell quờn i cỏc phộp bound trc ú n cỏc bin khi ú ta cú th thc hin bound li mt tờn bin ó s dng I DataType ca Erlang 1 S v biu din s trong Erlang Cỏc s c cung cp cỏc cỏch vit thụng thng vi cỏc... kiu d liu tớch -Cỏc ca ngụn ng Erlang, l mt tp hp gm cỏc thnh phn d liu cú cỏc kiu khỏc nhau Nu nh trong C ta s dng cu trỳc struct to nờn kiu d liu cú cu trỳc th hin tớch Cỏc ca cỏc kiu d liu n gin, bng cỏch khai bỏo mt struct nh sau: struct point { Int x; Int y; } P; Vi Erlang kiu d liu Tuple c hai bỏo nh sau: {Term1, ,TermN} [Type text] 15 Tỡm hiu v ngụn ng lp trỡnh Erlang Nh ta thy cỏc thnh phn... {lastName,armstrong} 4> P = {person, F, L} {person,{firstName,joe},{lastName,armstrong}} Cỏc trng trong tuple ca erlang khụng cú tờn, vy lm th no ta cú th ly giỏ tr trong tuple Nh ta ó bit, du = trong erlang c s dng nh mt toỏn t gỏn trong C, nhng thc cht nú l mt toỏn t pattern matching, nú c erlang s dng trong nhiu chc nng khỏc nhau, trong ú cú vic ly d liu t tuple ly d liu t tuple, n gin nh sau: 1>Point... phn t trong 1 list, 1 danh sỏch tham s, Du ô ; ằ l du th hin cỏc v ca mt cõu lnh [Type text] 11 Tỡm hiu v ngụn ng lp trỡnh Erlang ng sau du % l mt cõu chỳ thớch, ton b nhng kớ t ng sau du % cho n cui dũng u c coi l cõu chỳ thớch v s khụng c dch bi Erlang compiler NG NGHA C BN CA ERLANG H Bin i vi ngụn ng - Variable i vi mt ngụn ng lp trỡnh thỡ bin l mt thnh phn rt quan trng ca ngụn ng nú l ni th hin... H a 4> T [2,{c,4}] 5> L2 = [d|T] [d,2,{c,4}] 6> length(L1) 3 [Type text] 19 Tỡm hiu v ngụn ng lp trỡnh Erlang 7> length([]) 0 Tp hp cỏc hm lm vic vi List c trong th vin lists String l mt chui ký t trong Erlang c biu din bng cỏch trong du nhỏy kộp (), nhng chui ký t khụng phi l mt kiu d liu trong Erlang nú l mt cỏch vit ngn ca mt list Vớ d nh chui Hello l vit tt ca list [$h,$e,$l,$l,$o] hoc list [104,101,108,108,111]... bin trong Erlang c dựng mt phộp gỏn (=) mt ln duy nht khi mun bit giỏ tr ca bin no thỡ ch cn gừ tờn bin ra Mt khi X ó cú giỏ tr c nh ta cú th s dng nú, tuy nhiờn khi ta cú ý nh gỏn li cho X mt giỏ tr khỏc thỡ shell s bỏo li, bi vỡ th nht bin trong Erlang khụng phi l mt bin nh ta vn quan nim nh trong cỏc ngụn ng lp trỡnh khỏc nh Java hay C, th hai du = khụng phi l toỏn t gỏn Cỏc bin trong Erlang cú... vi bin thụng qua tờn Trong Erlang thỡ tờn ca bin c th hin bng mt cm cỏc ký t bt u bng mt ch cỏi in hoa Khi thc thi chng trỡnh chy trờn shell mi thnh phn u c gỏn vi mt bin c th Bin s thng c khai bỏo di dng bt u bng ch cỏi in hoa hay l du gch di v cú th bao gm cỏc ký t s v ch, gch chõn v @ Vớ d: X Name1 PhoneNumber Phone_number _ _Height Cỏc bin s c rng buc ti giỏ tr ang s dng Erlang ch cho phộp 1 bin . trình Erlang TIỂU LUẬN MÔN HỌC Đề tài : Tìm hiểu về ngôn ngữ lập trình ERLANG. [Type text] 1 Tìm hiểu về ngôn ngữ lập trình Erlang LỜI NÓI ĐẦU 3 ERLANG VÀ HỆ THỐNG HỖ TRỢ LẬP TRÌNH VỚI ERLANG. THỐNG TỪ VỰNG CỦA ERLANG 11 NGỮ NGHĨA CƠ BẢN CỦA ERLANG 12 ĐIỀU KHIỂN LUỒNG TRONG ERLANG 21 MÔI TRƯỜNG THỰC THI CỦA ERLANG 44 KẾT LUẬN 64 [Type text] 2 Tìm hiểu về ngôn ngữ lập trình Erlang LỜI NÓI. hướng lập trình tương tranh của Erlang. [Type text] 3 Tìm hiểu về ngôn ngữ lập trình Erlang ERLANG VÀ HỆ THỐNG HỖ TRỢ LẬP TRÌNH VỚI ERLANG A. Giới thiệu chung Erlang là một ngôn ngữ lập trình

Ngày đăng: 11/11/2014, 14:52

TỪ KHÓA LIÊN QUAN

TRÍCH ĐOẠN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w