繁体   English   中英

如何在AST中查找标识符的用法?

[英]How to find usages of an identifer in an AST?

给定以下AST定义和示例代码,给定标识符在树中的位置,找到标识符的所有用法的最佳算法是什么?


AST Definition

type Literal
   = Char  of  char          // character literal
   | String of string        // string literal
   | Integer of  int         // integer literal
   | Float  of  float        // floating point literal   
   | Double of double 
   | Unit

type SrcCol = { startColumn : int; endColumn : int }

type SrcLine = { startLine : int; endLine : int }

type SrcLoc = { srcFilename : string; srcLine : SrcLine; srcColumn : SrcCol }     

type Pat =
    | PVar of 'a
    | PApp of Pat * Pat
    | PLit of Literal    
    | PWithTy of Pat * Type

type Exp 
    = Var      of 'a                           // variable    
    | Lam      of Pat list * Exp       // lambda abstraction
    | App      of Exp * Exp            // application    
    | Let      of Pat * Exp * Exp  // local definition    
    | Lit      of Literal                      // literal 
    | WithTy   of Exp * Type



Sample Code:

let f x = let g x = x                               
          g x 

AST instance of Sample Code
  [Let
                   (PApp
                      (PVar
                         ("f",
                          {srcFilename =
                            "test.fs";
                           srcLine = {startLine = 1;
                                      endLine = 1;};
                           srcColumn = {startColumn = 4;
                                        endColumn = 5;};}),
                       PVar
                         ("x",
                          {srcFilename =
                            "test.fs";
                           srcLine = {startLine = 1;
                                      endLine = 1;};
                           srcColumn = {startColumn = 6;
                                        endColumn = 7;};})),
                    Let
                      (PApp
                         (PVar
                            ("g",
                             {srcFilename =
                               "test.fs";
                              srcLine = {startLine = 1;
                                         endLine = 1;};
                              srcColumn = {startColumn = 14;
                                           endColumn = 15;};}),
                          PVar
                            ("x",
                             {srcFilename =
                               "test.fs";
                              srcLine = {startLine = 1;
                                         endLine = 1;};
                              srcColumn = {startColumn = 16;
                                           endColumn = 17;};})),
                       Var
                         ("x",
                          {srcFilename =
                            "test.fs";
                           srcLine = {startLine = 1;
                                      endLine = 1;};
                           srcColumn = {startColumn = 20;
                                        endColumn = 21;};}),
                       App
                         (Var
                            ("g",
                             {srcFilename =
                               "test.fs";
                              srcLine = {startLine = 2;
                                         endLine = 2;};
                              srcColumn = {startColumn = 10;
                                           endColumn = 11;};}),
                          Var
                            ("x",
                             {srcFilename =
                               "test.fs";
                              srcLine = {startLine = 2;
                                         endLine = 2;};
                              srcColumn = {startColumn = 12;
                                           endColumn = 13;};}))),Lit Unit)]


基本上,需要使用所需属性的过滤器对树节点进行任何类型的枚举。 深度优先搜索(在另一个答案中提出)是枚举节点的一种方法。

但是,对于特定树节点中的特定标识符,通常想要知道的是它代表什么“声明的实体”? 否则,您会找到所有引用,但它们引用的是不同的实体,通常没有帮助。

这要求为所讨论的应用程序语言构建符号表,然后在标识符节点和符号表条目之间构建映射。 一个简单的枚举器不会建立符号表。

在“创建”身份的节点的子树中的DFS呢?

看看我周末破解的实现:

http://fsharprefactor.codeplex.com/

似乎可以工作了:)

FSharpRefactor 0.1(预览版)在Visual Studio画廊上发布。

http://visualstudiogallery.msdn.microsoft.com/339cbae9-911d-4f99-9033-3c3564676f45?SRC=Home

干杯;)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM