2009-02-25 6 views
27

Tôi tự hỏi cách khớp mẫu thường được triển khai. ví dụ trong Erlang bạn có nghĩ rằng nó được thực hiện ở cấp byte-mã (có một bytecode cho nó để nó được thực hiện hiệu quả) hay nó được tạo ra như một loạt các lệnh (chuỗi bytecode) bởi trình biên dịch? nó là một điều hữu ích như vậy mà tôi chỉ phải đặt nó vào một ngôn ngữ đồ chơi Im xây dựng thank you very muchkhớp mẫu - triển khai

(liên kết nhiều hơn thì hoan nghênh)

Trả lời

18

Bạn có thể xem những gì xảy ra nếu biên dịch một số mã

-module(match). 
-export([match/1]). 
match(X) -> {a,Y} = X. 

Khi bạn muốn xem làm thế nào trông giống như core

> c(match, to_core). 

hoặc

$ erlc +to_core match.erl 

kết quả là

module 'match' ['match'/1, 
       'module_info'/0, 
       'module_info'/1] 
    attributes [] 
'match'/1 = 
    %% Line 3 
    fun (_cor0) -> 
     case _cor0 of 
      <{'a',Y}> when 'true' -> 
       _cor0 
      (<_cor1> when 'true' -> 
       primop 'match_fail' 
        ({'badmatch',_cor1}) 
      -| ['compiler_generated']) 
     end 
'module_info'/0 = 
    fun() -> 
     call 'erlang':'get_module_info' 
      ('match') 
'module_info'/1 = 
    fun (_cor0) -> 
     call 'erlang':'get_module_info' 
      ('match', _cor0) 

Nếu bạn muốn xem mã asm của chùm bạn có thể làm

> c(match, 'S'). 

hoặc

$ erlc -S match.erl 

và kết quả

{module, match}. %% version = 0 

{exports, [{match,1},{module_info,0},{module_info,1}]}. 

{attributes, []}. 

{labels, 8}. 


{function, match, 1, 2}. 
    {label,1}. 
    {func_info,{atom,match},{atom,match},1}. 
    {label,2}. 
    {test,is_tuple,{f,3},[{x,0}]}. 
    {test,test_arity,{f,3},[{x,0},2]}. 
    {get_tuple_element,{x,0},0,{x,1}}. 
    {test,is_eq_exact,{f,3},[{x,1},{atom,a}]}. 
    return. 
    {label,3}. 
    {badmatch,{x,0}}. 


{function, module_info, 0, 5}. 
    {label,4}. 
    {func_info,{atom,match},{atom,module_info},0}. 
    {label,5}. 
    {move,{atom,match},{x,0}}. 
    {call_ext_only,1,{extfunc,erlang,get_module_info,1}}. 


{function, module_info, 1, 7}. 
    {label,6}. 
    {func_info,{atom,match},{atom,module_info},1}. 
    {label,7}. 
    {move,{x,0},{x,1}}. 
    {move,{atom,match},{x,0}}. 
    {call_ext_only,2,{extfunc,erlang,get_module_info,2}}. 

Như bạn thấy {test,is_tuple,..., {test,test_arity,..., {get_tuple_element,...{test,is_eq_exact,... là hướng dẫn cách kết hợp này được thực hiện trong chùm và nó được chuyển trực tiếp thành byte-mã của dầm.

Trình biên dịch Erlang được thực hiện trong chính Erlang và bạn có thể xem từng giai đoạn biên dịch trong mã nguồn của mô-đun compile và chi tiết trong các mô đun phụ thuộc.

+1

câu trả lời tuyệt vời, rất nhiều thông tin tuyệt vời ở đây (đặc biệt là các chỉ thị biên dịch). cảm ơn bạn – deepblue

+0

+1 cho câu trả lời tuyệt vời. –

2

Điều tốt nhất tôi có thể đề nghị là để biên dịch lên một số hàm thử nghiệm và xem xét mã được tạo.

erlc -S test.erl 

tạo test.S khá dễ đọc.

Để trả lời câu hỏi, các mẫu khớp được xây dựng một cách hiệu quả từ các hoạt động nguyên thủy hơn. Đây là một phần của mã từ một mệnh đề hàm khớp với {X, [H | T]}.

{test,is_tuple,{f,1},[{x,0}]}. 
{test,test_arity,{f,1},[{x,0},2]}. 
{get_tuple_element,{x,0},0,{x,1}}. 
{get_tuple_element,{x,0},1,{x,2}}. 
{test,is_nonempty_list,{f,4},[{x,2}]}. 
11

Nếu bạn muốn xây dựng trình ghép mẫu của riêng mình, có paper by Scott and Ramseypaper by Luc Maranget, cả hai đều mô tả cách biên dịch mẫu thành cây quyết định hiệu quả (còn gọi là câu lệnh chuyển lồng nhau).

+0

tuyệt vời. đánh giá cao nó, trông giống như rất nhiều công cụ hữu ích – deepblue

+0

+1 Các liên kết rất thú vị, một bài đọc hay. –

28

Mô tả rất tốt về việc đối chiếu mẫu được đưa ra trong "Việc triển khai các ngôn ngữ lập trình chức năng" của Simon Peyton Jones. Đó là một chút cũ nhưng một cuốn sách rất tốt. Nó cũng chứa, trong số những thứ khác, một mô tả của việc biên dịch danh sách comprehensions.

Trình biên dịch Erlang sử dụng cả hai thuật toán này trong sách.

+1

cảm ơn. Tôi đã tải xuống cuốn sách này một thời gian nhưng không bao giờ có thời gian để đọc nó. làm thế nào để bạn biết rằng Erlang sử dụng các thuật toán từ nó? – deepblue

+6

Xin lỗi vì đã không trả lời trước đó, sớm hơn nhiều. Lý do tôi biết là tôi thực hiện biên dịch mô hình phù hợp cho trình biên dịch hiện tại và đây là nơi tôi đã lấy thuật toán từ. – rvirding

+1

hoạt động;). cảm ơn vì đã làm việc trên erlang, hơi kỳ quặc nhưng lại tạo ra hơi thở không khí trong lành. làm cho cuộc sống của tôi trở thành một nơi tốt hơn cho chắc chắn – deepblue