⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 base_ast.sa

📁 SRI international 发布的OAA框架软件
💻 SA
字号:
(* 

  ANTLR Translator Generator
  Project led by Terence Parr at http://www.jGuru.com
  Software rights: http://www.antlr.org/RIGHTS.html
 
  $Id: base_ast.sa,v 1.1.1.1 2002/01/02 19:59:09 agno Exp $

*)

partial class ANTLR_BASE_AST{AST < $ANTLR_AST{AST} } < $ANTLR_AST{AST} , $STR is

   attr down  : AST;
   attr right : AST;

   attr verbose_string_conversion : BOOL; -- init false
   attr token_names : ARRAY{STR};
   
   -- Add a node to the end of the child list for this node 
   add_child( node : AST ) is
      if ( void(node) ) then
	 return;
      end;
      t : AST := first_child;
      if ( ~void(t) ) then
	 loop while! ( ~void(t.next_sibling) );
	    t := t.next_sibling;
	 end;
	 t.next_sibling := node;
      else
	 first_child := node;
      end;
   end;
   
   do_work_for_find_all( sibling : AST, v : FLIST{AST}, target : AST, partial_match : BOOL ) is

      -- Start walking sibling lists, looking for matches.
      loop while!( ~void(sibling) );

	 if ( ( partial_match and sibling.equals_tree_partial( target ) )
	     or ( ~partial_match and sibling.equals_tree( target ) ) ) then
	    v := v.push( sibling );
	 end;

	 -- regardless of match or not, check any children for matches
	 if ( ~void(sibling.first_child) ) then
	    do_work_for_find_all( sibling.first_child, v, target, partial_match);
	 end;
	 
	 sibling := sibling.next_sibling;
      end;
   end;
   
   -- Is node t equal to this in terms of token type and text? 
   equals( t : AST ) : BOOL is 
      if ( void(t) ) then
	 return false;
      end;
      return ( text = t.text ) and ( ttype = t.ttype );
   end;
   
   -- Is t an exact structural and equals() match of this tree.  The
   -- 'this' reference is considered the start of a sibling list.
   equals_list( t : AST ) : BOOL is
      sibling : AST;

      -- the empty tree is not a match of any non-void tree.
      if ( void(t) ) then
	 return false;
      end;

      -- Otherwise, start walking sibling lists.  First mismatch, return false.
      sibling := self;
      loop while!( ~void(sibling) and ~void(t) );

	 -- as a quick optimization, check roots first.
	 if ( ~sibling.equals(t) ) then
	    return false;
	 end;

	 -- if roots match, do full list match test on children.
	 if ( ~void(sibling.first_child) ) then
	    if ( ~sibling.first_child.equals_list( t.first_child ) ) then
	       return false;
	    end;
	 -- sibling has no kids, make sure t doesn't either
	 elsif ( ~void(t.first_child) ) then
	    return false;
	 end;
	 
	sibling := sibling.next_sibling;
	t := t.next_sibling;
      end;

      if ( void(sibling) and void(t) ) then
	 return true;
      end;

      -- one sibling list has more than the other
      return false;

   end;

   -- Is 'sub' a subtree of this list?
   -- The siblings of the root are NOT ignored.
   equals_list_partial( sub : AST ) : BOOL is
      sibling : AST;

      -- the empty tree is always a subset of any tree.
      if ( void(sub) ) then
	 return true;
      end;
	
      -- Otherwise, start walking sibling lists.  First mismatch, return false.
      sibling := self;
      loop while! ( ~void(sibling) and ~void(sub) );

	 -- as a quick optimization, check roots first.
	 if ( ~sibling.equals(sub) ) then
	    return false;
	 end;

	 -- if roots match, do partial list match test on children.
	 if ( ~void(sibling.first_child) ) then
	    if ( ~sibling.first_child.equals_list_partial( sub.first_child ) ) then
	       return false;
	    end;
	 end;
	       
	 sibling := sibling.next_sibling;
	 sub := sub.next_sibling;

      end;
      
      if ( void(sibling) and ~void(sub) ) then
	 -- nothing left to match in this tree, but subtree has more
	 return false;
      end;

      -- either both are void or sibling has more, but subtree doesn't	
      return true;
   end;

   -- Is tree rooted at 'this' equal to 't'?  The siblings
   -- of 'this' are ignored.
   equals_tree( t : AST ) : BOOL is
      
      -- check roots first.
      if ( ~self.equals(t) ) then
	 return false;
      end;

      -- if roots match, do full list match test on children.
      if ( ~void(first_child) ) then
	 if ( ~first_child.equals_list(t.first_child) ) then
	    return false;
	 end;
      elsif ( ~void(t.first_child) ) then
	 -- sibling has no kids, make sure t doesn't either
	 return false;
      end;
      return true;		
   end;

   -- Is 't' a subtree of the tree rooted at 'this'?  The siblings
   -- of 'this' are ignored. 
	
   equals_tree_partial( sub : AST ) : BOOL is 

      -- the empty tree is always a subset of any tree.
      if ( void(sub) ) then
	 return true;
      end;
	
      -- check roots first.
      if ( ~self.equals(sub) ) then
	 return false;
      end;

      -- if roots match, do full list partial match test on children.
      if ( ~void(first_child) ) then
	 if ( ~first_child.equals_list_partial(sub.first_child) ) then
		  return false;
	 end;
      end;

      return true;		
   end;

   -- Walk the tree looking for all exact subtree matches.  Return
   -- a list of subtree roots found herein.
   find_all( target : AST ) : ARRAY{AST} is
      roots : FLIST{AST} := #FLIST{AST}(10);

      -- the empty tree cannot result in an enumeration
      if ( ~void(target) ) then
	  -- find all matches recursively
	 do_work_for_find_all( self, roots, target, false ); 
      end;

      return roots.array;
   end;

   -- Walk the tree looking for all subtrees.  Return
   -- the list of subtree roots found herein.

   find_all_partial( sub : AST ) : ARRAY{AST} is
      roots : FLIST{AST} := #FLIST{AST}(10);

      -- the empty tree cannot result in an enumeration
      if ( ~void(sub) ) then
	 -- find all matches recursively
	 do_work_for_find_all( self, roots, sub, true );
      end;
      
      return roots.array;
   end;
   
   -- Get the first child of this node; void if not children
   first_child : AST is
      return down;
   end;
   
   -- Get the next sibling in line after this one
   next_sibling : AST is
      return right;
   end;

   -- Get the token text for this node
   stub text : STR;
   
   -- Set the token text for this node
   stub text( text : STR );
   
   -- Get the token type for this node
   stub ttype : INT;

   -- Set the token type for this node
   stub ttype( typ : INT );

   -- Remove all children
   remove_children is
      down := void;
   end;
   
   first_child( c : AST ) is 
      down := c;
   end;

   next_sibling( n : AST ) is
      right := n;
   end;

   str : STR is
      b : STR;
      -- if verbose and type name not AST as text (keyword probably)
      if ( verbose_string_conversion and
	  text.upper /= token_names[ttype].upper and
	  text.upper /= ANTLR_UTIL::strip_front_back( token_names[ttype].upper ,"\"","\"") ) then
	 
	 b := "[" + text + ",<" + token_names[ttype] + ">]";
	 return b;
      end;
      return text;
   end;
   
   -- Print out a child-sibling tree in LISP notation
   str_list : STR is
      t : AST := self;
      ts : STR := "";

      if ( ~void(t.first_child) ) then
	 ts := ts + " (";
      end;

      ts := ts + " " + str;

      if ( ~void(t.first_child) ) then
	 ts := ts + t.first_child.str_list + " )";
      end;

      if ( ~void(t.next_sibling) ) then
	 ts := ts + t.next_sibling.str_list;
      end;
      
      return ts;
   end;
   

   str_tree : STR is 
      t : AST := self;
      ts : STR;

      if ( ~void(t.first_child) ) then 
	 ts := ts + " (";
      end;

      ts := ts + " " + str;

      if ( ~void(t.first_child) ) then
	 ts := ts + t.first_child.str_list + " )";
      end;

      return ts;
   end;

end;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -