erl_syntax.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 2,346 行 · 第 1/5 页

ERL
2,346
字号
%% =====================================================================%% This library is free software; you can redistribute it and/or modify%% it under the terms of the GNU Lesser General Public License as%% published by the Free Software Foundation; either version 2 of the%% License, or (at your option) any later version.%%%% This library is distributed in the hope that it will be useful, but%% WITHOUT ANY WARRANTY; without even the implied warranty of%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU%% Lesser General Public License for more details.%%%% You should have received a copy of the GNU Lesser General Public%% License along with this library; if not, write to the Free Software%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307%% USA%%%% $Id$%%%% @copyright 1997-2006 Richard Carlsson%% @author Richard Carlsson <richardc@it.uu.se>%% @end%% =====================================================================%% @doc Abstract Erlang syntax trees.%%%% This module defines an abstract data type for representing Erlang%% source code as syntax trees, in a way that is backwards compatible%% with the data structures created by the Erlang standard library%% parser module <code>erl_parse</code> (often referred to as "parse%% trees", which is a bit of a misnomer). This means that all%% <code>erl_parse</code> trees are valid abstract syntax trees, but the%% reverse is not true: abstract syntax trees can in general not be used%% as input to functions expecting an <code>erl_parse</code> tree.%% However, as long as an abstract syntax tree represents a correct%% Erlang program, the function <a%% href="#revert-1"><code>revert/1</code></a> should be able to%% transform it to the corresponding <code>erl_parse</code>%% representation.%%%% A recommended starting point for the first-time user is the%% documentation of the <a%% href="#type-syntaxTree"><code>syntaxTree()</code></a> data type, and%% the function <a href="#type-1"><code>type/1</code></a>.%%%% <h3><b>NOTES:</b></h3>%%%% This module deals with the composition and decomposition of%% <em>syntactic</em> entities (as opposed to semantic ones); its%% purpose is to hide all direct references to the data structures used%% to represent these entities. With few exceptions, the functions in%% this module perform no semantic interpretation of their inputs, and%% in general, the user is assumed to pass type-correct arguments - if%% this is not done, the effects are not defined.%%%% With the exception of the <code>erl_parse</code> data structures,%% the internal representations of abstract syntax trees are subject to%% change without notice, and should not be documented outside this%% module. Furthermore, we do not give any guarantees on how an abstract%% syntax tree may or may not be represented, <em>with the following%% exceptions</em>: no syntax tree is represented by a single atom, such%% as <code>none</code>, by a list constructor <code>[X | Y]</code>, or%% by the empty list <code>[]</code>. This can be relied on when writing%% functions that operate on syntax trees.%% @type syntaxTree(). An abstract syntax tree. The%% <code>erl_parse</code> "parse tree" representation is a subset of the%% <code>syntaxTree()</code> representation.%%%% Every abstract syntax tree node has a <em>type</em>, given by the%% function <a href="#type-1"><code>type/1</code></a>. Each node also%% has associated <em>attributes</em>; see <a%% href="#get_attrs-1"><code>get_attrs/1</code></a> for details. The%% functions <a href="#make_tree-2"><code>make_tree/2</code></a> and <a%% href="#subtrees-1"><code>subtrees/1</code></a> are generic%% constructor/decomposition functions for abstract syntax trees. The%% functions <a href="#abstract-1"><code>abstract/1</code></a> and <a%% href="#concrete-1"><code>concrete/1</code></a> convert between%% constant Erlang terms and their syntactic representations. The set of%% syntax tree nodes is extensible through the <a%% href="#tree-2"><code>tree/2</code></a> function.%%%% A syntax tree can be transformed to the <code>erl_parse</code>%% representation with the <a href="#revert-1"><code>revert/1</code></a>%% function.-module(erl_syntax).-export([type/1,	 is_leaf/1,	 is_form/1,	 is_literal/1,	 abstract/1,	 concrete/1,	 revert/1,	 revert_forms/1,	 subtrees/1,	 make_tree/2,	 update_tree/2,	 meta/1,	 get_pos/1,	 set_pos/2,	 copy_pos/2,	 get_precomments/1,	 set_precomments/2,	 add_precomments/2,	 get_postcomments/1,	 set_postcomments/2,	 add_postcomments/2,	 has_comments/1,	 remove_comments/1,	 copy_comments/2,	 join_comments/2,	 get_ann/1,	 set_ann/2,	 add_ann/2,	 copy_ann/2,	 get_attrs/1,	 set_attrs/2,	 copy_attrs/2,	 flatten_form_list/1,	 cons/2,	 list_head/1,	 list_tail/1,	 is_list_skeleton/1,	 is_proper_list/1,	 list_elements/1,	 list_length/1,	 normalize_list/1,	 compact_list/1,	 application/2,	 application/3,	 application_arguments/1,	 application_operator/1,	 arity_qualifier/2,	 arity_qualifier_argument/1,	 arity_qualifier_body/1,	 atom/1,	 is_atom/2,	 atom_value/1,	 atom_literal/1,	 atom_name/1,	 attribute/1,	 attribute/2,	 attribute_arguments/1,	 attribute_name/1,	 binary/1,	 binary_field/1,	 binary_field/2,	 binary_field/3,	 binary_field_body/1,	 binary_field_types/1,	 binary_field_size/1,	 binary_fields/1,	 block_expr/1,	 block_expr_body/1,	 case_expr/2,	 case_expr_argument/1,	 case_expr_clauses/1,	 catch_expr/1,	 catch_expr_body/1,	 char/1,	 is_char/2,	 char_value/1,	 char_literal/1,	 clause/2,	 clause/3,	 clause_body/1,	 clause_guard/1,	 clause_patterns/1,	 comment/1,	 comment/2,	 comment_padding/1,	 comment_text/1,	 cond_expr/1,	 cond_expr_clauses/1,	 conjunction/1,	 conjunction_body/1,	 disjunction/1,	 disjunction_body/1,	 eof_marker/0,	 error_marker/1,	 error_marker_info/1,	 float/1,	 float_value/1,	 float_literal/1,	 form_list/1,	 form_list_elements/1,	 fun_expr/1,	 fun_expr_arity/1,	 fun_expr_clauses/1,	 function/2,	 function_arity/1,	 function_clauses/1,	 function_name/1,	 generator/2,	 generator_body/1,	 generator_pattern/1,	 if_expr/1,	 if_expr_clauses/1,	 implicit_fun/1,	 implicit_fun/2,	 implicit_fun/3,	 implicit_fun_name/1,	 infix_expr/3,	 infix_expr_left/1,	 infix_expr_operator/1,	 infix_expr_right/1,	 integer/1,	 is_integer/2,	 integer_value/1,	 integer_literal/1,	 list/1,	 list/2,	 list_comp/2,	 list_comp_body/1,	 list_comp_template/1,	 list_prefix/1,	 list_suffix/1,	 macro/1,	 macro/2,	 macro_arguments/1,	 macro_name/1,	 match_expr/2,	 match_expr_body/1,	 match_expr_pattern/1,	 module_qualifier/2,	 module_qualifier_argument/1,	 module_qualifier_body/1,	 nil/0,	 operator/1,	 operator_literal/1,	 operator_name/1,	 parentheses/1,	 parentheses_body/1,	 prefix_expr/2,	 prefix_expr_argument/1,	 prefix_expr_operator/1,	 qualified_name/1,	 qualified_name_segments/1,	 query_expr/1,	 query_expr_body/1,	 receive_expr/1,	 receive_expr/3,	 receive_expr_action/1,	 receive_expr_clauses/1,	 receive_expr_timeout/1,	 record_access/2,	 record_access/3,	 record_access_argument/1,	 record_access_field/1,	 record_access_type/1,	 record_expr/2,	 record_expr/3,	 record_expr_argument/1,	 record_expr_fields/1,	 record_expr_type/1,	 record_field/1,	 record_field/2,	 record_field_name/1,	 record_field_value/1,	 record_index_expr/2,	 record_index_expr_field/1,	 record_index_expr_type/1,	 rule/2,	 rule_arity/1,	 rule_clauses/1,	 rule_name/1,	 size_qualifier/2,	 size_qualifier_argument/1,	 size_qualifier_body/1,	 string/1,	 is_string/2,	 string_value/1,	 string_literal/1,	 text/1,	 text_string/1,	 try_expr/2,	 try_expr/3,	 try_expr/4,	 try_after_expr/2,	 try_expr_body/1,	 try_expr_clauses/1,	 try_expr_handlers/1,	 try_expr_after/1,	 class_qualifier/2,	 class_qualifier_argument/1,	 class_qualifier_body/1,	 tuple/1,	 tuple_elements/1,	 tuple_size/1,	 underscore/0,	 variable/1,	 variable_name/1,	 variable_literal/1,	 warning_marker/1,	 warning_marker_info/1,	 tree/1,	 tree/2,	 data/1,	 is_tree/1]).%% =====================================================================%% IMPLEMENTATION NOTES:%%%% All nodes are represented by tuples of arity 2 or greater, whose%% first element is an atom which uniquely identifies the type of the%% node. (In the backwards-compatible representation, the interpretation%% is also often dependent on the context; the second element generally%% holds the position information - with a couple of exceptions; see%% `get_pos' and `set_pos' for details). In the documentation of this%% module, `Pos' is the source code position information associated with%% a node; usually, this is a positive integer indicating the original%% source code line, but no assumptions are made in this module%% regarding the format or interpretation of position information. When%% a syntax tree node is constructed, its associated position is by%% default set to the integer zero.%% =====================================================================-define(NO_UNUSED, true).%% =====================================================================%% Declarations of globally used internal data structures%% =====================================================================%% `com' records are used to hold comment information attached to a%% syntax tree node or a wrapper structure.%%%% #com{pre :: Pre, post :: Post}%%%%	Pre = Post = [Com]%%	Com = syntaxTree()%%%%	type(Com) = comment-record(com, {pre = [],	      post = []}).%% `attr' records store node attributes as an aggregate.%%%% #attr{pos :: Pos, ann :: Ann, com :: Comments}%%%%	Pos = term()%%	Ann = [term()]%%	Comments = none | #com{}%%%% where `Pos' `Ann' and `Comments' are the corresponding values of a%% `tree' or `wrapper' record.-record(attr, {pos = 0,	       ann = [],	       com = none}).%% `tree' records represent new-form syntax tree nodes.%%%% Tree = #tree{type :: Type, attr :: Attr, data :: Data}%%%%	Type = atom()%%	Attr = #attr{}%%	Data = term()%%%%	is_tree(Tree) = true-record(tree, {type,	       attr = #attr{},	       data}).%% `wrapper' records are used for attaching new-form node information to%% `erl_parse' trees.%%%% Wrapper = #wrapper{type :: Type, attr :: Attr, tree :: ParseTree}%%%%	Type = atom()%%	Attr = #attr{}%%	ParseTree = term()%%%%	is_tree(Wrapper) = false-record(wrapper, {type,		  attr = #attr{},		  tree}).%% =====================================================================%%%%			Exported functions%%%% =====================================================================%% =====================================================================%% @spec type(Node::syntaxTree()) -> atom()%%%% @doc Returns the type tag of <code>Node</code>. If <code>Node</code>%% does not represent a syntax tree, evaluation fails with reason%% <code>badarg</code>. Node types currently defined by this module are:%% <p><center><table border="1">%%  <tr>%%   <td>application</td>%%   <td>arity_qualifier</td>%%   <td>atom</td>%%   <td>attribute</td>%%  </tr><tr>%%   <td>binary</td>%%   <td>binary_field</td>%%   <td>block_expr</td>%%   <td>case_expr</td>%%  </tr><tr>%%   <td>catch_expr</td>%%   <td>char</td>%%   <td>class_qualifier</td>%%   <td>clause</td>%%  </tr><tr>%%   <td>comment</td>%%   <td>cond_expr</td>%%   <td>conjunction</td>%%   <td>disjunction</td>%%  </tr><tr>%%   <td>eof_marker</td>%%   <td>error_marker</td>%%   <td>float</td>%%   <td>form_list</td>%%  </tr><tr>%%   <td>fun_expr</td>%%   <td>function</td>%%   <td>generator</td>%%   <td>if_expr</td>%%  </tr><tr>%%   <td>implicit_fun</td>%%   <td>infix_expr</td>%%   <td>integer</td>%%   <td>list</td>%%  </tr><tr>%%   <td>list_comp</td>%%   <td>macro</td>%%   <td>match_expr</td>%%   <td>module_qualifier</td>%%  </tr><tr>%%   <td>nil</td>%%   <td>operator</td>%%   <td>parentheses</td>%%   <td>prefix_expr</td>%%  </tr><tr>%%   <td>qualified_name</td>%%   <td>query_expr</td>%%   <td>receive_expr</td>%%   <td>record_access</td>%%  </tr><tr>%%   <td>record_expr</td>%%   <td>record_field</td>%%   <td>record_index_expr</td>%%   <td>rule</td>%%  </tr><tr>%%   <td>size_qualifier</td>%%   <td>string</td>%%   <td>text</td>%%   <td>try_expr</td>%%  </tr><tr>%%   <td>tuple</td>%%   <td>underscore</td>%%   <td>variable</td>%%   <td>warning_marker</td>%%  </tr>%% </table></center></p>%% <p>The user may (for special purposes) create additional nodes%% with other type tags, using the <code>tree/2</code> function.</p>

⌨️ 快捷键说明

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