00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "config.h"
00021 #include "vscan.h"
00022
00023 #include "robIO.h"
00024
00025 #ifndef BUILDING_DOX
00026 # include <assert.h>
00027 # include <boost/regex.hpp>
00028 # include <FlexLexer.h>
00029 # include <map>
00030 # include <sstream>
00031 #endif
00032
00033 using namespace StreamDecorator;
00034 using std::string;
00035
00041 class VFlexLexer: public yyFlexLexer {
00042 public:
00043 VFlexLexer(std::istream &stream, string fileName):
00044 yyFlexLexer(&stream, &std::cerr),
00045 fileName_(fileName),
00046 hasError_(false)
00047 {
00048 }
00050 bool hasError() const {
00051 return hasError_;
00052 }
00054 EToken readNext() {
00055 return static_cast<EToken>
00056 (this->yylex());
00057 }
00059 void postError(const char *msg) {
00060 this->LexerError(msg);
00061 }
00062 protected:
00064 virtual void LexerOutput(const char *buf, int size) {
00065 string msg(buf, size);
00066 this->LexerError(msg.c_str());
00067 }
00069 #if DEBUG_VSCAN
00070 virtual void LexerError(const char *msg) {
00071 this->hasError_ = true;
00072 std::ostream &str = *(this->yyout);
00073 str << Error(E_ERROR, fileName_, msg, lineno(), "lexical error")
00074 << std::endl;
00075 }
00076 #else
00077 virtual void LexerError(const char *) { }
00078 #endif
00079 private:
00080 string fileName_;
00081 bool hasError_;
00082 };
00083
00087 class FlexVScan: public IVScan {
00088 public:
00089 FlexVScan(std::istream &stream, string fileName) {
00090 flex_ = new VFlexLexer(stream, fileName);
00091 }
00092 virtual ~FlexVScan() {
00093 delete flex_;
00094 }
00095 virtual bool readNext(string &);
00096 virtual bool hasError() const {
00097 return flex_->hasError();
00098 }
00099 private:
00100 VFlexLexer *flex_;
00101 };
00102
00103 IVScan* VScanFactory::createVScan(std::istream &stream, std::string fileName) {
00104 return new FlexVScan(stream, fileName);
00105 }
00106
00107 bool FlexVScan::readNext(string &data) {
00108 readNext:
00109 if (!flex_->readNext())
00110 return false;
00111
00112 std::string tmp(flex_->YYText());
00113 const boost::regex re("^#BEGIN#([^#]*)#END#$");
00114 boost::smatch result;
00115 if (!boost::regex_match(tmp, result, re)) {
00116 flex_->postError("FlexVScan::readnext, internal");
00117 goto readNext;
00118 }
00119
00120 data = result[1];
00121
00122 #if DEBUG_VSCAN_OUTPUT
00123 std::cerr << Color(C_LIGHT_PURPLE) << "VScan" << Color(C_NO_COLOR) << " --> "
00124 << data << std::endl;
00125 #endif
00126
00127 return true;
00128 }
00129