gen_tcp:send failing silently

Gerd Flaig gerd@REDACTED
Mon Feb 23 10:31:50 CET 2004


Samuel Tardieu <sam@REDACTED> writes:

> Implement a full fledged parser for the IRC protocol then. Here is
> mine:

out of curiosity - which parser is more efficient, yours or the
following one? It is used like this:

  1. Get a parser by calling parser(InputFunction). InputFunction
     should take one argument, a msg record. parser() returns a parser
     function which takes one string argument.

-record(msg, {prefix=[], cmd=[], params=[]}).

  2. Call the parser function with your first chunk of data. Whenever
     a message is complete, the InputFunciton is called. The return
     value of the parser function is a new parser function which
     should be called with the next chunk.

Suggestions for code improvement are welcome.

        Goodbyte, Gerd.

P.S.: As you can see, I'm also toying around with Erlang and IRC. I'm
      currently experimenting with a minimal IRC proxy in Erlang.

parser(IF) ->
    fun(String) ->
 	    parse(IF, String)
    end.

parse(IF, "") ->
    parser(IF);
parse(IF, [$\n | Rest]) ->
    parse(IF, Rest);
parse(IF, [$: | Rest]) ->
    prefix(IF, "", Rest);
parse(IF, String) ->
    cmd(IF, "", "", String).

prefix(IF, P, "") ->
    fun(String) ->
	    prefix(IF, P, String)
    end;
prefix(IF, P, [$  | Rest]) ->
    cmd(IF, lists:reverse(P), "", Rest);
prefix(IF, P, [C | Rest]) ->
    prefix(IF, [C|P], Rest).

cmd(IF, Prefix, Cmd, "") ->
    fun(String) ->
	    cmd(IF, Prefix, Cmd, String)
    end;
cmd(IF, Prefix, Cmd, [$  | Rest]) ->
    params(IF, #msg{prefix=Prefix, cmd= lists:reverse(Cmd)}, "", Rest);
cmd(IF, Prefix, Cmd, [C | Rest]) ->
    cmd(IF, Prefix, [C | Cmd], Rest).

params(IF, M, P, "") ->
    fun(String) ->
	    params(IF, M, P, String)
    end;
params(IF, M, P, Str = [$\r | Rest]) ->
    last_param(IF, M, P, Str);
params(IF, M, P, [$: | Rest]) ->
    last_param(IF, M, "", Rest);
params(IF, M = #msg{params=Ps}, P, [$  | Rest]) -> 
    params(IF, M#msg{params = [lists:reverse(P) | Ps]}, "", Rest);
params(IF, M, P, [C | Rest]) ->
    params(IF, M, [C | P], Rest).

last_param(IF, M = #msg{params=Ps}, P, [$\r | Rest]) ->
    IF(M#msg{params= lists:reverse([lists:reverse(P) | Ps])}),
    parse(IF, Rest);
last_param(IF, M, P, [C | Rest]) ->
    last_param(IF, M, [C | P], Rest).


-- 
Gerd Flaig                     Technik                gerd@REDACTED
Bei Schlund + Partner AG       Brauerstraße 48      D-76135 Karlsruhe
 Physics is like sex: sure, it may give some practical results,
 but that's not why we do it. -- Richard Feynman



More information about the erlang-questions mailing list