1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2000-2015. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20 21-module(xref_scanner). 22 23-include("xref.hrl"). 24 25-export([scan/1]). 26 27scan(Chars) -> 28 case erl_scan:string(Chars) of 29 {ok, Tokens, _Line} -> 30 {ok, lex(a1(Tokens))}; 31 {error, {Line,Module,Info}, _EndLine} -> 32 {error, Module:format_error(Info), Line} 33 end. 34 35a1([{'-',N},{integer,N,1} | L]) -> 36 [{integer,N,-1} | a1(L)]; 37a1([T | L]) -> 38 [T | a1(L)]; 39a1([]) -> 40 []. 41 42-define(MFA(M,F,A,N), {atom,N,M}, {':',_}, {atom,_,F}, {'/',_}, {integer,_,A}). 43-define(MFA2(M,F,A,N), 44 {'{',N},{atom,_,M},{',',_},{atom,_,F},{',',_},{integer,_,A},{'}',_}). 45-define(DECL(N1,N2,T), {':',N1},{var,N2,T}). 46 47lex([{atom,N,V1},{'->',_},{atom,_,V2} | L]) -> 48 Constant = {constant, unknown, edge, {V1,V2}}, 49 [{edge,N,Constant} | lex(L)]; 50lex([{'{',N},{atom,_,V1},{',',_},{atom,_,V2},{'}',_} | L]) -> 51 Constant = {constant, unknown, edge, {V1,V2}}, 52 [{edge,N,Constant} | lex(L)]; 53lex([?MFA(M,F,A,N),{'->',_},?MFA(M2,F2,A2,_) | L]) -> 54 Constant = {constant, 'Fun', edge, {{M,F,A},{M2,F2,A2}}}, 55 [{edge,N,Constant} | lex(L)]; 56lex([?MFA(M,F,A,N) | L]) -> 57 Constant = {constant, 'Fun', vertex, {M,F,A}}, 58 [{vertex,N,Constant} | lex(L)]; 59lex([{'{',N},?MFA2(M,F,A,_),{',',_},?MFA2(M2,F2,A2,_),{'}',_} | L]) -> 60 Constant = {constant, 'Fun', edge, {{M,F,A},{M2,F2,A2}}}, 61 [{edge,N,Constant} | lex(L)]; 62lex([?MFA2(M,F,A,N) | L]) -> 63 Constant = {constant, 'Fun', vertex, {M,F,A}}, 64 [{vertex,N,Constant} | lex(L)]; 65lex([?DECL(N1,N2,Decl) | L]) -> 66 case is_type(Decl) of 67 false -> [?DECL(N1, N2, Decl) | lex(L)]; 68 true -> [{decl,N1,Decl} | lex(L)] 69 end; 70lex([{':',N},{'=',_} | L]) -> 71 [{':=',N} | lex(L)]; 72lex([{'||',N},{'|',_} | L]) -> 73 [{'|||',N} | lex(L)]; 74lex([V={var,N,Var} | L]) -> 75 T = case is_type(Var) of 76 false -> V; 77 true -> {cast,N,Var} 78 end, 79 [T | lex(L)]; 80lex([T | Ts]) -> 81 [T | lex(Ts)]; 82lex([]) -> 83 [{'$end', erl_anno:new(?XREF_END_LINE)}]. 84 85is_type('Rel') -> true; 86is_type('App') -> true; 87is_type('Mod') -> true; 88is_type('Fun') -> true; 89is_type('Lin') -> true; 90is_type('LLin') -> true; 91is_type('XLin') -> true; 92is_type('ELin') -> true; 93is_type('XXL') -> true; 94is_type(_) -> false. 95