Created
July 21, 2012 20:40
-
-
Save khayrov/3157086 to your computer and use it in GitHub Desktop.
stock quote parsing with Ragel
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CFLAGS=-O2 | |
CXXFLAGS=-O2 | |
all: parser | |
parser.cpp: parser.rl | |
ragel -G2 $^ -o $@ | |
parser.o: parser.cpp RawQuote.h | |
RawQuote.o: RawQuote.cpp RawQuote.h | |
parser: parser.o RawQuote.o | |
g++ $^ -o $@ | |
.PHONY: clean | |
clean: | |
rm -f parser parser.cpp *.o |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string> | |
#include <iostream> | |
#include "RawQuote.h" | |
/** | |
Fields: | |
1003 - Symbol | |
2002 - Last | |
2003 - Bid | |
2004 - Ask | |
2005 - Bid Size | |
2006 - Ask Size | |
2007 - Last Size | |
2008 - Yesterday?s close | |
2009 - The High for today | |
2010 - The Low for today | |
2011 - The Open for today | |
2012 - The total volume traded for today | |
2013 - Uptick/Downtick | |
Uptick - 20020 | |
Downtick - 20021 | |
2014 - TimeStamp (HH:MM:SS) | |
2015 - Date (MM/DD/YYYY) | |
**/ | |
%%{ | |
machine quote; | |
write data; | |
}%% | |
bool ParseQuote(const std::string &message, RawQuote "e) | |
{ | |
int cs; | |
const char *p = message.data(), *pe = message.data() + message.size(); | |
const char *symstart; | |
int intval; | |
double realval; | |
double intpart, fracpart, tenpow; | |
#define ASSIGN_INT(fieldname) quote.fieldname = intval; quote.has##fieldname = true; | |
#define ASSIGN_REAL(fieldname) quote.fieldname = realval; quote.has##fieldname = true; | |
%%{ | |
integer = ( digit @ { intval = intval * 10 + (fc - '0'); } )+ | |
> { intval = 0; } ; | |
intpart = ( digit @ { intpart = intpart * 10 + (fc - '0'); } )+ | |
> { intpart = 0.0; } ; | |
fracpart = ( digit @ { fracpart += (fc - '0') * tenpow; tenpow *= 0.1; } )+ | |
> { fracpart = 0.0; tenpow = 0.1; } ; | |
real = intpart @ { realval = intpart; } | |
| (intpart '.' fracpart ) @ { realval = intpart + fracpart; }; | |
symbol = '1003=' ( | |
[^;]+ | |
> { symstart = p; } | |
@ { quote.Symbol.assign(symstart, p + 1); quote.hasSymbol = true; } | |
) ; | |
last = '2002=' real @ { ASSIGN_REAL(Last); } ; | |
bid = '2003=' real @ { ASSIGN_REAL(Bid); } ; | |
ask = '2004=' real @ { ASSIGN_REAL(Ask); } ; | |
bidsize = '2005=' integer @ { ASSIGN_INT(BidSize); } ; | |
asksize = '2006=' integer @ { ASSIGN_INT(AskSize); } ; | |
lastsize = '2007=' integer @ { ASSIGN_INT(LastSize); } ; | |
close = '2008=' real @ { ASSIGN_REAL(Close); } ; | |
high = '2009=' real @ { ASSIGN_REAL(High); } ; | |
low = '2010=' real @ { ASSIGN_REAL(Low); } ; | |
open = '2011=' real @ { ASSIGN_REAL(Open); } ; | |
total = '2012=' real @ { ASSIGN_REAL(Volume); } ; | |
uptick = '2013=' ( | |
'20020' @ { quote.Uptick = true; } | | |
'20021' @ { quote.Uptick = false; } | |
) @ { quote.hasUptick = true; } ; | |
timestamp = '2014=' | |
integer @ { ASSIGN_INT(Hour); } ':' | |
integer @ { ASSIGN_INT(Minute); } ':' | |
integer @ { ASSIGN_INT(Second); } ; | |
date = '2015=' | |
integer @ { ASSIGN_INT(Month); } '/' | |
integer @ { ASSIGN_INT(Day); } '/' | |
integer @ { ASSIGN_INT(Year); } ; | |
genericfield = digit+ '=' [^;]+ ; | |
field = symbol | last | bid | ask | bidsize | asksize | lastsize | | |
close | high | low | open | total | uptick | | |
timestamp | date | | |
genericfield ; | |
main := '1|' (field ';')* field ; | |
write init; | |
write exec; | |
}%% | |
#undef ASSIGN_INT | |
#undef ASSIGN_REAL | |
return cs >= %%{ write first_final; }%%; | |
} | |
int main() | |
{ | |
std::string message = "1|2025=US;2026=USD;1003=EUR/USD;2087=10070;2089=0;2042=FX;2090=0;2002=1.21899;2003=1.21899;2004=1.21907;2005=500000;2006=1000000;2007=150;2008=1.22376;2009=1.22479;2010=1.21842;2011=1.22377;2012=28603324;2013=20021;2014=06:43:15;2015=07/12/2012"; | |
RawQuote quote; | |
bool result; | |
for (int i = 0; i < 1000000; ++i) | |
{ | |
result = ParseQuote(message, quote); | |
} | |
std::cout << (result ? "Success" : "Failure") << std::endl | |
<< quote; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <ostream> | |
#include "RawQuote.h" | |
std::ostream &operator <<(std::ostream &os, const RawQuote "e) | |
{ | |
#define PRINT_FIELD(fieldname) if (quote.has##fieldname) { \ | |
os << #fieldname << " = " << quote.fieldname << '\n'; \ | |
} | |
PRINT_FIELD(Symbol); | |
PRINT_FIELD(Last); | |
PRINT_FIELD(Bid); | |
PRINT_FIELD(Ask); | |
PRINT_FIELD(BidSize); | |
PRINT_FIELD(AskSize); | |
PRINT_FIELD(LastSize); | |
PRINT_FIELD(Close); | |
PRINT_FIELD(High); | |
PRINT_FIELD(Low); | |
PRINT_FIELD(Open); | |
PRINT_FIELD(Volume); | |
PRINT_FIELD(Uptick); | |
PRINT_FIELD(Hour); | |
PRINT_FIELD(Minute); | |
PRINT_FIELD(Second); | |
PRINT_FIELD(Month); | |
PRINT_FIELD(Day); | |
PRINT_FIELD(Year); | |
#undef PRINT_FIELD | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef RAWQUOTE_H | |
#define RAWQUOTE_H | |
#include <string> | |
#include <ostream> | |
struct RawQuote | |
{ | |
std::string Symbol; | |
double Last; | |
double Bid; | |
double Ask; | |
int BidSize; | |
int AskSize; | |
int LastSize; | |
double Close; | |
double High; | |
double Low; | |
double Open; | |
double Volume; | |
bool Uptick; | |
int Hour; | |
int Minute; | |
int Second; | |
int Month; | |
int Day; | |
int Year; | |
bool hasSymbol; | |
bool hasLast; | |
bool hasBid; | |
bool hasAsk; | |
bool hasBidSize; | |
bool hasAskSize; | |
bool hasLastSize; | |
bool hasClose; | |
bool hasHigh; | |
bool hasLow; | |
bool hasOpen; | |
bool hasVolume; | |
bool hasUptick; | |
bool hasHour; | |
bool hasMinute; | |
bool hasSecond; | |
bool hasMonth; | |
bool hasDay; | |
bool hasYear; | |
}; | |
std::ostream &operator <<(std::ostream &os, const RawQuote "e); | |
#endif // RAWQUOTE_H |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment