dialect.parsing

Functions related to parsing IRC events.

IRC events come in very heterogeneous forms along the lines of:

:sender.address.tld TYPE [args...] :content

:sender!~ident@address.tld 123 [args...] :content

The number and syntax of arguments for types vary wildly. As such, one common parsing routine can't be used; there are simply too many exceptions. The beginning :sender.address.tld is *almost* always the same form, but only almost. It's guaranteed to be followed by the type however, which come either in alphanumeric name (e.g. PRIVMSG, INVITE, MODE, ...), or in numeric form of 001 to 999 inclusive.

What we can do then is to parse this type, and interpret the arguments following as befits it.

This translates to large switches, which can't be helped. There are simply too many variations, which switches lend themselves well to. You could make it into long if...else if chains, but it would just be the same thing in a different form. Likewise a nested function is not essentially different from a switch case.

IRCParser parser;

string fromServer = ":zorael!~NaN@address.tld MODE #channel +v nickname";
IRCEvent event = parser.toIRCEvent(fromServer);

with (event)
{
    assert(type == IRCEvent.Type.MODE);
    assert(sender.nickname == "zorael");
    assert(sender.ident == "~NaN");
    assert(sender.address == "address.tld");
    assert(target.nickname == "nickname");
    assert(channel == "#channel");
    assert(aux[0] = "+v");
}

string alsoFromServer = ":cherryh.freenode.net 435 oldnick newnick #d " ~
    ":Cannot change nickname while banned on channel";
IRCEvent event2 = parser.toIRCEvent(alsoFromServer);

with (event2)
{
    assert(type == IRCEvent.Type.ERR_BANONCHAN);
    assert(sender.address == "cherryh.freenode.net");
    assert(channel == "#d");
    assert(target.nickname == "oldnick");
    assert(content == "Cannot change nickname while banned on channel");
    assert(aux[0] == "newnick");
    assert(num == 435);
}

string furtherFromServer = ":kameloso^!~ident@81-233-105-99-no80.tbcn.telia.com NICK :kameloso_";
IRCEvent event3 = parser.toIRCEvent(furtherFromServer);

with (event3)
{
    assert(type == IRCEvent.Type.NICK);
    assert(sender.nickname == "kameloso^");
    assert(sender.ident == "~ident");
    assert(sender.address == "81-233-105-99-no80.tbcn.telia.com");
    assert(target.nickname = "kameloso_");
}

See the /tests directory for more example parses.

Members

Functions

toIRCEvent
IRCEvent toIRCEvent(IRCParser parser, string raw)

Parses an IRC string into an IRCEvent.

Structs

IRCParser
struct IRCParser

Parser that takes raw IRC strings and produces IRCEvents based on them.

Meta