Little Languages with Lex, Yacc, and MFC by Jason Shankel Example 1: CRichEditCntrItem *CreateClientItem(_reobject *)const { return NULL; } Example 2: void CSlideDoc::Serialize(CArchive& ar) { CRichEditDoc::Serialize(ar); } Example 3: void CSlideView::OnCompile() { CString compileString = ""; EDITSTREAM es = {reinterpret_cast(&compileString), 0, SlideViewEditStreamCallBack}; GetRichEditCtrl().StreamOut(SF_TEXT, es); } Example 4: Add SlideMessage to SlideView.cpp: extern "C" void SlideMessage(char *message) { AfxMessageBox(message); } Listing One /* This callback is used by CSlideView's rich text edit control to stream text into a CString dwCookie - pointer to a CString pbBuff - pointer to text cb - size of pbBuff pcb - gets number of bytes copied */ static DWORD CALLBACK SlideViewEditStreamCallBack( DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb) { CString *compileString = reinterpret_cast(dwCookie); for (int i=0;i(pbBuff[i]); *pcb = cb; return 0; } Listing Two %{ /* This bison file implements the grammar rules for recognizing a sequence of comma-delimited strings */ void SlideMessage(char *message); void yyerror(char *); int yylex(void); %} %token TOKEN %% start: /*empty*/ | little_list {SlideMessage("Stringlist Found");} ; little_list : TOKEN | little_list ',' TOKEN ; %% Listing Three %{ /* This flex file implements the rules for tokenizing strings */ #include "slpars_t.h" #include #include /* Redefine input source (see article) */ int SlideYYInput(char *buf,int max_size); #undef YY_INPUT #define YY_INPUT(buf,result,max_size) \ (result = SlideYYInput(buf,max_size)) %} %% [A-z][A-z0-9]* { return TOKEN;}; [ \t\n] {/*ignore whitespace*/}; . {return yytext[0];}; %% void SlideMessage(char *message); int yyparse(); static char *SlideInputStream; /* yywrap and yyerror are required by flex and bison */ void yyerror(char *err) { SlideMessage(err); } int yywrap() { return 1; } /* YY_INPUT redirects lex to get its input from this function. It just copies data from a local static char * assigned in SlideCompile. */ int SlideYYInput(char *buf,int max_size) { int n = min(max_size,(int)strlen(SlideInputStream)); if (n > 0) { memcpy(buf,SlideInputStream,n); SlideInputStream += n; } return n; } /* SlideCompile runs the compiler. Called from OnCompile in CSlideView */ void SlideCompile(char *inputStream) { SlideInputStream = inputStream; yyrestart(0); yyparse(); } Listing 4 /* OnCompile streams text from the rich edit control into a local CString and sends the CString to SlideCompile for processing by lex and yacc */ extern "C" void SlideCompile(char *inputStream); void CSlideView::OnCompile() { CString compileString = ""; EDITSTREAM es = {reinterpret_cast(&compileString), 0, SlideViewEditStreamCallBack}; GetRichEditCtrl().StreamOut(SF_TEXT, es); if (es.dwError == 0) { SlideCompile(const_cast(LPCTSTR(compileString))); } } 4