Metaquot:识别列表模式并存储结果列表

问题描述 投票:0回答:1

我将以下属性附加到节点

[@profiling.mark [ "label1"; "label2"; "label3" ]]
,这给了我这个 AST:

[{attr_name = {txt = "profiling.mark"};
 attr_payload =
  PStr
   [{pstr_desc =
      Pstr_eval
       ({pexp_desc =
          Pexp_construct ({txt = Lident "::"},
           Some
            {pexp_desc =
              Pexp_tuple
               [{pexp_desc =
                  Pexp_constant
                   (Pconst_string ("label1", ...));
                 pexp_loc_stack = []};
                {pexp_desc =
                  Pexp_construct ({txt = Lident "::"},
                   Some
                    {pexp_desc =
                      Pexp_tuple
                       [{pexp_desc =
                          Pexp_constant
                           (Pconst_string ("label2", ...));
                         pexp_loc_stack = []};
                        {pexp_desc =
                          Pexp_construct
                           ({txt = Lident "::"},
                           Some
                            {pexp_desc =
                              Pexp_tuple
                               [{pexp_desc =
                                  Pexp_constant
                                   (Pconst_string ("label3",
                                     ...));
                                 pexp_loc_stack = []};
                                {pexp_desc =
                                  Pexp_construct
                                   ({txt = Lident "[]"},
                                   None);
                                 pexp_loc_stack = []}];
                             pexp_loc_stack = []});
                         pexp_loc_stack = []}];
                     pexp_loc_stack = []});
                 pexp_loc_stack = []}];
             pexp_loc_stack = []});
         pexp_loc_stack = []},
       ...)}]}]

如果我想提取标签,我需要破坏一个

Pstr_construct
,所以我这样做了:

Ppxlib.PStr                                                 
  [                                                         
    [%stri                                                  
      [%e?                                                  
        {                                                   
          pexp_desc =                                       
            Pexp_construct                                  
              ( { txt = Lident "::"; _ },                   
                Some { pexp_desc = Pexp_tuple labels; _ } );
          _;                                                
        }]];                                                
  ] ->                                                      
  { metadata = labels }                                     

首先,我尝试使用metaquot来销毁列表,但找不到方法。但最重要的是

labels
expression list
而不是
expression
,所以我无法用
[%e labels]
重建它。

然后我想出了一个不同的方法:

Ppxlib.PStr                                                        
  [                                                                
    [%stri                                                         
      [%e?                                                         
        {                                                          
          pexp_desc =                                              
            Pexp_construct ({ txt = Lident "::"; _ }, Some labels);
          _;                                                       
        }]];                                                       
  ] ->                                                             
  { metadata = Some labels }                                       

但是当我阅读预处理文件时,我看到了这个:

("label1", ["label2"; "label3"])
。我没有列表,但有一个包含元素和列表的元组。就我而言,我需要
["label1"; "label2"; "label3"]

我是不是做错了什么或者遗漏了什么?

ocaml ppx
1个回答
0
投票

提取列表可以通过

完成
let rec extract_list =function
  | [%expr [%e? h] :: [%e? r] ] -> Option.map (List.cons h) (extract_list r)
  | [%expr [] ] -> Some []
  | _ -> None

重建列表类似:

let rec embed_list loc = function
  | [] -> [%expr []]
  | [e] -> [%expr [[%e e]] ]
  | a::q -> [%expr [%e a]::[%e embed_list loc q] ]
© www.soinside.com 2019 - 2025. All rights reserved.