00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "conf_feature.h"
00026
00027
00028 #include <string>
00029
00030 using namespace std;
00031 using namespace IXE;
00032 using namespace Tanl::Text;
00033
00034 namespace Parser {
00035
00036 static TokenPath* nextPath(char const*& line);
00037
00042 static bool check(char const*& line, char const* str)
00043 {
00044 char const* start = line;
00045
00046 char const* tok = next_token_line(line, " \r\t");
00047 if (::strstr(tok, str) == tok) {
00048 line = start + ::strlen(str);
00049 return true;
00050 }
00051 return false;
00052 }
00053
00054 static TokenPath* parse(string& tok, char const*& line)
00055 {
00056 char* endptr;
00057 long pos = strtol(tok.c_str(), &endptr, 10);
00058 if (tok.c_str() != endptr)
00059 return new TokenPath(pos);
00060 TokenPath::Direction dir = (TokenPath::Direction)TokenPath::get(tok);
00061 if (dir == -1) {
00062 cerr << "Wrong token specification: " << tok << endl;
00063 return 0;
00064 }
00065
00066 if (!check(line, "(")) {
00067 cerr << "Wrong token syntax after: " << tok << " at: " << line << endl;
00068 return 0;
00069 }
00070 TokenPath* tp = nextPath(line);
00071 if (!tp)
00072 return 0;
00073 tp->add(dir);
00074
00075 if (!check(line, ")")) {
00076 cerr << "Wrong token syntax after: " << tok << " at: " << line << endl;
00077 return 0;
00078 }
00079 return tp;
00080 }
00081
00087 static TokenPath* nextPath(char const*& line)
00088 {
00089 char const* st = next_token_line(line, " \r\t()");
00090 if (!st) return 0;
00091 string tok(st, line - st);
00092 return parse(tok, line);
00093 }
00094
00095 void conf_feature::parseValue(char const*& line)
00096 {
00097 char const* st = next_token_line(line, " \r\t");
00098 string feature(st, line - st);
00099 if (value.find(feature.c_str()) == value.end())
00100 value[::strdup(feature.c_str())];
00101 set<TokenPath*>& paths = value[feature.c_str()];
00102 TokenPath* tp;
00103 while ((tp = nextPath(line)))
00104 paths.insert(tp);
00105 }
00106
00107 void conf_feature::serialize(std::ostream& os)
00108 {
00109 FOR_EACH (FeatureSpecs, value, fit) {
00110 os << name() << '\t' << fit->first;
00111 FOR_EACH (set<TokenPath*>, fit->second, tit)
00112 os << ' ' << **tit;
00113 os << endl;
00114 }
00115 }
00116
00117 }