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

applyTags
void applyTags(IRCEvent event)

This is technically a postprocessor but it's small enough that we can just keep it in here (and provide the functionality as pure and @safe).

onISUPPORT
void onISUPPORT(IRCParser parser, IRCEvent event, string slice)

Handles RPL_ISUPPORT events.

onMode
void onMode(IRCParser parser, IRCEvent event, string slice)

Handle MODE changes.

onMyInfo
void onMyInfo(IRCParser parser, IRCEvent event, string slice)

Handle RPL_MYINFO events.

onNotice
void onNotice(IRCParser parser, IRCEvent event, string slice)

Handle NOTICE events.

onPRIVMSG
void onPRIVMSG(IRCParser parser, IRCEvent event, string slice)

Handle QUERY and CHAN messages (PRIVMSG).

parseBasic
void parseBasic(IRCParser parser, IRCEvent event)

Parses the most basic of IRC events; PING, ERROR, PONG, NOTICE (plus NOTICE AUTH), and AUTHENTICATE.

parseGeneralCases
void parseGeneralCases(IRCParser parser, IRCEvent event, string slice)

Takes a slice of a raw IRC string and continues parsing it into an IRCEvent struct.

parsePrefix
void parsePrefix(IRCParser parser, IRCEvent event, string slice)

Takes a slice of a raw IRC string and starts parsing it into an IRCEvent struct.

parseSpecialcases
void parseSpecialcases(IRCParser parser, IRCEvent event, string slice)

Takes a slice of a raw IRC string and continues parsing it into an IRCEvent struct.

parseTypestring
void parseTypestring(IRCParser parser, IRCEvent event, string slice)

Takes a slice of a raw IRC string and continues parsing it into an IRCEvent struct.

postparseSanityCheck
void postparseSanityCheck(IRCParser parser, IRCEvent event)

Checks for some specific erroneous edge cases in an IRCEvent.

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