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 + -
显示快捷键?