From this post, we will have to learn Flex and Bison, which are assumed to have very bizarre grammars to write and understand. Fortunately, we will step forwardly from Flex standalone, Flex+Bison and Flex+Bison+C finally. Please kindly note that all these post would NOT teach you to become the expert of Flex/Bison but show the basic ideas using Flex/Bison to write a stack of a protocol for text decoding, like Itevad. Here we will make sure our Flex/Bison work and try to make a lexer at first using Flex. Let’s go!
/* Install and make sure flex/bison work */ [root@localhost ItevadBin]# which flex /usr/bin/flex [root@localhost ItevadBin]# flex -V flex version 2.5.4 [root@localhost ItevadBin]# which bison /usr/bin/bison [root@localhost ItevadBin]# bison -V bison (GNU Bison) 2.3 Written by Robert Corbett and Richard Stallman. Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. [root@localhost ItevadBin]# /* Flex stand alone for scanning Text Itevad Protocol */ [root@localhost ItevadBin]# cat itevadTxtFlexStandAlone.l /* Itevad Protocol Text Encoding Lexical Analyzer Stand Alone Example April 6, 2012 http://daveti.blog.com Reference: itevad.abnf NOTE: This is a Flex file NOT Lex! */ %{ #include <stdlib.h> #include <string.h> #include <stdio.h> enum yytokentype { DOT, LSB, RSB, EQUAL, COLON, LBRKT, RBRKT, SLASH, ItevadToken, TransToken, ReplyToken, AskToken, AnswerToken, quotedString, IPv4Address, NUMBER }; %} /* Configure our lexer */ %option stack noyywrap case-insensitive %% "." { return DOT; } /* Dot */ "[" { return LSB; } /* Left square bracket */ "]" { return RSB; } /* Right square bracket */ "=" { return EQUAL; } /* Equal */ ":" { return COLON; } /* Colon */ "{" { return LBRKT; } /* Left brace */ "}" { return RBRKT; } /* Right brace */ "/" { return SLASH; } /* Slash */ "Itevad" { return ItevadToken; } /* Itevad Token */ "Transaction" { return TransToken; } /* Transaction Token */ "Reply" { return ReplyToken; } /* Reply Token */ "Ask" { return AskToken; } /* Ask Token */ "Answer" { return AnswerToken; } /* Answer Token */ "(.*)" { printf("Debug - quoted string: %sn", yytext); return quotedString; } /* Quoted String */ [0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3} { /* IPv4 address handling here */ printf("Debug - IPv4 address: %sn", yytext); return IPv4Address; } /* IPv4 Address */ [0-9]+ { printf("Debug - number: %sn", yytext); return NUMBER; } /* Number */ [ trnv] { /* Ignore */ } /* White spaces */ %% int main( int argc, char **argv) { int token; while ( token = yylex()) { printf("Token: %dn", token); } return 0; } [root@localhost ItevadBin]# /* Generate and run itevadFlexBin */ [root@localhost ItevadBin]# flex itevadTxtFlexStandAlone.l [root@localhost ItevadBin]# gcc -o itevadFlexBin lex.yy.c -lfl [root@localhost ItevadBin]# ./itevadFlexBin Itevad/1 [49.49.49.49]:7777 Transaction = 65535 { Ask = "who r you?" } Token: 8 Token: 7 Debug - number: 1 Token: 15 Token: 1 Debug - IPv4 address: 49.49.49.49 Token: 14 Token: 2 Token: 4 Debug - number: 7777 Token: 15 Token: 9 Token: 3 Debug - number: 65535 Token: 15 Token: 5 Token: 11 Token: 3 Debug - quoted string: "who r you?" Token: 13 Token: 6 [root@localhost ItevadBin]#