Current section
Files
Jump to
Current section
Files
src/erlang_scan.xrl
%%% File : erlang_scan.xrl
%%% Author : Robert Virding
%%% Purpose : Tkoen definitions for Erlang.
Definitions.
O = [0-7]
D = [0-9]
H = [0-9a-fA-F]
U = [A-Z]
L = [a-z]
A = ({U}|{L}|{D}|_|@)
WS = ([\000-\s]|%.*)
Rules.
{D}+\.{D}+((E|e)(\+|\-)?{D}+)? :
{token,{float,TokenLine,list_to_float(TokenChars)}}.
{D}+#{H}+ : base(TokenLine, TokenChars).
{D}+ : {token,{integer,TokenLine,list_to_integer(TokenChars)}}.
{L}{A}* : Atom = list_to_atom(TokenChars),
{token,case reserved_word(Atom) of
true -> {Atom,TokenLine};
false -> {atom,TokenLine,Atom}
end}.
'(\\\^.|\\.|[^'])*' :
%% Strip quotes.
S = lists:sublist(TokenChars, 2, TokenLen - 2),
case catch list_to_atom(string_gen(S)) of
{'EXIT',_} -> {error,"illegal atom " ++ TokenChars};
Atom -> {token,{atom,TokenLine,Atom}}
end.
({U}|_){A}* : {token,{var,TokenLine,list_to_atom(TokenChars)}}.
"(\\\^.|\\.|[^"])*" :
%% Strip quotes.
S = lists:sublist(TokenChars, 2, TokenLen - 2),
{token,{string,TokenLine,string_gen(S)}}.
\$(\\{O}{O}{O}|\\\^.|\\.|.) :
{token,{integer,TokenLine,cc_convert(TokenChars)}}.
-> : {token,{'->',TokenLine}}.
:- : {token,{':-',TokenLine}}.
=/= : {token,{'=/=',TokenLine}}.
== : {token,{'==',TokenLine}}.
=:= : {token,{'=:=',TokenLine}}.
/= : {token,{'/=',TokenLine}}.
>= : {token,{'>=',TokenLine}}.
=< : {token,{'=<',TokenLine}}.
<= : {token,{'<=',TokenLine}}.
\+\+ : {token,{'++',TokenLine}}.
-- : {token,{'--',TokenLine}}.
[]()[}{|!?/;:,.*+#<>=-] :
{token,{list_to_atom(TokenChars),TokenLine}}.
\.{WS} : {end_token,{dot,TokenLine}}.
{WS}+ : skip_token.
Erlang code.
-export([reserved_word/1]).
reserved_word('after') -> true;
reserved_word('begin') -> true;
reserved_word('case') -> true;
reserved_word('catch') -> true;
reserved_word('end') -> true;
reserved_word('fun') -> true;
reserved_word('if') -> true;
reserved_word('let') -> true;
reserved_word('of') -> true;
reserved_word('query') -> true;
reserved_word('receive') -> true;
reserved_word('when') -> true;
reserved_word('bnot') -> true;
reserved_word('not') -> true;
reserved_word('div') -> true;
reserved_word('rem') -> true;
reserved_word('band') -> true;
reserved_word('and') -> true;
reserved_word('bor') -> true;
reserved_word('bxor') -> true;
reserved_word('bsl') -> true;
reserved_word('bsr') -> true;
reserved_word('or') -> true;
reserved_word('xor') -> true;
reserved_word(_) -> false.
base(L, Cs) ->
H = string:chr(Cs, $#),
case list_to_integer(string:substr(Cs, 1, H-1)) of
B when B > 16 -> {error,"illegal base"};
B ->
case base(string:substr(Cs, H+1), B, 0) of
error -> {error,"illegal based number"};
N -> {token,{integer,L,N}}
end
end.
base([C|Cs], Base, SoFar) when C >= $0, C =< $9, C < Base + $0 ->
Next = SoFar * Base + (C - $0),
base(Cs, Base, Next);
base([C|Cs], Base, SoFar) when C >= $a, C =< $f, C < Base + $a - 10 ->
Next = SoFar * Base + (C - $a + 10),
base(Cs, Base, Next);
base([C|Cs], Base, SoFar) when C >= $A, C =< $F, C < Base + $A - 10 ->
Next = SoFar * Base + (C - $A + 10),
base(Cs, Base, Next);
base([_|_], _Base, _SoFar) -> error;
base([], _Base, N) -> N.
cc_convert([$$,$\\|Cs]) ->
hd(string_escape(Cs));
cc_convert([$$,C]) -> C.
string_gen([$\\|Cs]) ->
string_escape(Cs);
string_gen([C|Cs]) ->
[C|string_gen(Cs)];
string_gen([]) -> [].
string_escape([O1,O2,O3|S]) when
O1 >= $0, O1 =< $7, O2 >= $0, O2 =< $7, O3 >= $0, O3 =< $7 ->
[(O1*8 + O2)*8 + O3 - 73*$0|string_gen(S)];
string_escape([$^,C|Cs]) ->
[C band 31|string_gen(Cs)];
string_escape([C|Cs]) when C >= $\000, C =< $\s ->
string_gen(Cs);
string_escape([C|Cs]) ->
[escape_char(C)|string_gen(Cs)].
escape_char($n) -> $\n; %\n = LF
escape_char($r) -> $\r; %\r = CR
escape_char($t) -> $\t; %\t = TAB
escape_char($v) -> $\v; %\v = VT
escape_char($b) -> $\b; %\b = BS
escape_char($f) -> $\f; %\f = FF
escape_char($e) -> $\e; %\e = ESC
escape_char($s) -> $\s; %\s = SPC
escape_char($d) -> $\d; %\d = DEL
escape_char(C) -> C.