base_ast.sa
上传用户:afrynkmhm
上传日期:2007-01-06
资源大小:1262k
文件大小:7k
源码类别:

编译器/解释器

开发平台:

Others

  1. (* 
  2.   ANTLR Translator Generator
  3.   Project led by Terence Parr at http://www.jGuru.com
  4.   Software rights: http://www.antlr.org/RIGHTS.html
  5.  
  6.   $Id: //depot/code/org.antlr/release/antlr-2.7.0/lib/sather/Antlr/base_ast.sa#1 $
  7. *)
  8. partial class ANTLR_BASE_AST{AST < $ANTLR_AST{AST} } < $ANTLR_AST{AST} is
  9.    attr down  : AST;
  10.    attr right : AST;
  11.    attr verbose_string_conversion : BOOL; -- init false
  12.    attr token_names : ARRAY{STR};
  13.    
  14.    -- Add a node to the end of the child list for this node 
  15.    add_child( node : AST ) is
  16.       if ( void(node) ) then
  17.  return;
  18.       end;
  19.       t : AST := first_child;
  20.       if ( ~void(t) ) then
  21.  loop while! ( ~void(t.next_sibling) );
  22.     t := t.next_sibling;
  23.  end;
  24.  t.next_sibling := node;
  25.       else
  26.  first_child := node;
  27.       end;
  28.    end;
  29.    
  30.    do_work_for_find_all( sibling : AST, v : FLIST{AST}, target : AST, partial_match : BOOL ) is
  31.       -- Start walking sibling lists, looking for matches.
  32.       loop while!( ~void(sibling) );
  33.  if ( ( partial_match and sibling.equals_tree_partial( target ) )
  34.      or ( ~partial_match and sibling.equals_tree( target ) ) ) then
  35.     v := v.push( sibling );
  36.  end;
  37.  -- regardless of match or not, check any children for matches
  38.  if ( ~void(sibling.first_child) ) then
  39.     do_work_for_find_all( sibling.first_child, v, target, partial_match);
  40.  end;
  41.  
  42.  sibling := sibling.next_sibling;
  43.       end;
  44.    end;
  45.    
  46.    -- Is node t equal to this in terms of token type and text? 
  47.    equals( t : AST ) : BOOL is 
  48.       if ( void(t) ) then
  49.  return false;
  50.       end;
  51.       return ( text = t.text ) and ( ttype = t.ttype );
  52.    end;
  53.    
  54.    -- Is t an exact structural and equals() match of this tree.  The
  55.    -- 'this' reference is considered the start of a sibling list.
  56.    equals_list( t : AST ) : BOOL is
  57.       sibling : AST;
  58.       -- the empty tree is not a match of any non-void tree.
  59.       if ( void(t) ) then
  60.  return false;
  61.       end;
  62.       -- Otherwise, start walking sibling lists.  First mismatch, return false.
  63.       sibling := self;
  64.       loop while!( ~void(sibling) and ~void(t) );
  65.  -- as a quick optimization, check roots first.
  66.  if ( ~sibling.equals(t) ) then
  67.     return false;
  68.  end;
  69.  -- if roots match, do full list match test on children.
  70.  if ( ~void(sibling.first_child) ) then
  71.     if ( ~sibling.first_child.equals_list( t.first_child ) ) then
  72.        return false;
  73.     end;
  74.  -- sibling has no kids, make sure t doesn't either
  75.  elsif ( ~void(t.first_child) ) then
  76.     return false;
  77.  end;
  78.  
  79. sibling := sibling.next_sibling;
  80. t := t.next_sibling;
  81.       end;
  82.       if ( void(sibling) and void(t) ) then
  83.  return true;
  84.       end;
  85.       -- one sibling list has more than the other
  86.       return false;
  87.    end;
  88.    -- Is 'sub' a subtree of this list?
  89.    -- The siblings of the root are NOT ignored.
  90.    equals_list_partial( sub : AST ) : BOOL is
  91.       sibling : AST;
  92.       -- the empty tree is always a subset of any tree.
  93.       if ( void(sub) ) then
  94.  return true;
  95.       end;
  96.       -- Otherwise, start walking sibling lists.  First mismatch, return false.
  97.       sibling := self;
  98.       loop while! ( ~void(sibling) and ~void(sub) );
  99.  -- as a quick optimization, check roots first.
  100.  if ( ~sibling.equals(sub) ) then
  101.     return false;
  102.  end;
  103.  -- if roots match, do partial list match test on children.
  104.  if ( ~void(sibling.first_child) ) then
  105.     if ( ~sibling.first_child.equals_list_partial( sub.first_child ) ) then
  106.        return false;
  107.     end;
  108.  end;
  109.        
  110.  sibling := sibling.next_sibling;
  111.  sub := sub.next_sibling;
  112.       end;
  113.       
  114.       if ( void(sibling) and ~void(sub) ) then
  115.  -- nothing left to match in this tree, but subtree has more
  116.  return false;
  117.       end;
  118.       -- either both are void or sibling has more, but subtree doesn't
  119.       return true;
  120.    end;
  121.    -- Is tree rooted at 'this' equal to 't'?  The siblings
  122.    -- of 'this' are ignored.
  123.    equals_tree( t : AST ) : BOOL is
  124.       
  125.       -- check roots first.
  126.       if ( ~self.equals(t) ) then
  127.  return false;
  128.       end;
  129.       -- if roots match, do full list match test on children.
  130.       if ( ~void(first_child) ) then
  131.  if ( ~first_child.equals_list(t.first_child) ) then
  132.     return false;
  133.  end;
  134.       elsif ( ~void(t.first_child) ) then
  135.  -- sibling has no kids, make sure t doesn't either
  136.  return false;
  137.       end;
  138.       return true;
  139.    end;
  140.    -- Is 't' a subtree of the tree rooted at 'this'?  The siblings
  141.    -- of 'this' are ignored. 
  142.    equals_tree_partial( sub : AST ) : BOOL is 
  143.       -- the empty tree is always a subset of any tree.
  144.       if ( void(sub) ) then
  145.  return true;
  146.       end;
  147.       -- check roots first.
  148.       if ( ~self.equals(sub) ) then
  149.  return false;
  150.       end;
  151.       -- if roots match, do full list partial match test on children.
  152.       if ( ~void(first_child) ) then
  153.  if ( ~first_child.equals_list_partial(sub.first_child) ) then
  154.   return false;
  155.  end;
  156.       end;
  157.       return true;
  158.    end;
  159.    -- Walk the tree looking for all exact subtree matches.  Return
  160.    -- a list of subtree roots found herein.
  161.    find_all( target : AST ) : ARRAY{AST} is
  162.       roots : FLIST{AST} := #FLIST{AST}(10);
  163.       -- the empty tree cannot result in an enumeration
  164.       if ( ~void(target) ) then
  165.   -- find all matches recursively
  166.  do_work_for_find_all( self, roots, target, false ); 
  167.       end;
  168.       return roots.array;
  169.    end;
  170.    -- Walk the tree looking for all subtrees.  Return
  171.    -- the list of subtree roots found herein.
  172.    find_all_partial( sub : AST ) : ARRAY{AST} is
  173.       roots : FLIST{AST} := #FLIST{AST}(10);
  174.       -- the empty tree cannot result in an enumeration
  175.       if ( ~void(sub) ) then
  176.  -- find all matches recursively
  177.  do_work_for_find_all( self, roots, sub, true );
  178.       end;
  179.       
  180.       return roots.array;
  181.    end;
  182.    
  183.    -- Get the first child of this node; void if not children
  184.    first_child : AST is
  185.       return down;
  186.    end;
  187.    
  188.    -- Get the next sibling in line after this one
  189.    next_sibling : AST is
  190.       return right;
  191.    end;
  192.    -- Get the token text for this node
  193.    stub text : STR;
  194.    
  195.    -- Set the token text for this node
  196.    stub text( text : STR );
  197.    
  198.    -- Get the token type for this node
  199.    stub ttype : INT;
  200.    -- Set the token type for this node
  201.    stub ttype( typ : INT );
  202.    -- Remove all children
  203.    remove_children is
  204.       down := void;
  205.    end;
  206.    
  207.    first_child( c : AST ) is 
  208.       down := c;
  209.    end;
  210.    next_sibling( n : AST ) is
  211.       right := n;
  212.    end;
  213.    str : STR is
  214.       b : STR;
  215.       -- if verbose and type name not AST as text (keyword probably)
  216.       if ( verbose_string_conversion and
  217.   text.upper /= token_names[ttype].upper and
  218.   text.upper /= ANTLR_UTIL::strip_front_back( token_names[ttype].upper ,""",""") ) then
  219.  
  220.  b := "[" + text + ",<" + token_names[ttype] + ">]";
  221.  return b;
  222.       end;
  223.       return text;
  224.    end;
  225.    
  226.    -- Print out a child-sibling tree in LISP notation
  227.    str_list : STR is
  228.       t : AST := self;
  229.       ts : STR := "";
  230.       if ( ~void(t.first_child) ) then
  231.  ts := ts + " (";
  232.       end;
  233.       ts := ts + " " + str;
  234.       if ( ~void(t.first_child) ) then
  235.  ts := ts + t.first_child.str_list + " )";
  236.       end;
  237.       if ( ~void(t.next_sibling) ) then
  238.  ts := ts + t.next_sibling.str_list;
  239.       end;
  240.       
  241.       return ts;
  242.    end;
  243.    
  244.    str_tree : STR is 
  245.       t : AST := self;
  246.       ts : STR;
  247.       if ( ~void(t.first_child) ) then 
  248.  ts := ts + " (";
  249.       end;
  250.       ts := ts + " " + str;
  251.       if ( ~void(t.first_child) ) then
  252.  ts := ts + t.first_child.str_list + " )";
  253.       end;
  254.       return ts;
  255.    end;
  256. end;