00001 #include "PCNTools.h"
00002
00003 #include <iostream>
00004 #include <cstdlib>
00005
00006 namespace PCN
00007 {
00008
00009 const std::string chars = "'\\";
00010 const char& quote = chars[0];
00011 const char& slash = chars[1];
00012
00013
00014 inline char get(const std::string& in, int c)
00015 {
00016 if (c < 0 || c >= (int)in.size()) return 0;
00017 else return in[(size_t)c];
00018 }
00019
00020
00021 inline void eatws(const std::string& in, int& c)
00022 {
00023 while (get(in,c) == ' ') {
00024 c++;
00025 }
00026 }
00027
00028
00029 std::string getEscapedString(const std::string& in, int &c)
00030 {
00031 eatws(in,c);
00032 if (get(in,c++) != quote) return "ERROR";
00033 std::string res;
00034 char cur = 0;
00035 do {
00036 cur = get(in,c++);
00037 if (cur == slash) {
00038 res += get(in,c++);
00039 } else if (cur != quote) {
00040 res += cur;
00041 }
00042 } while (get(in,c) != quote && (c < (int)in.size()));
00043 c++;
00044 eatws(in,c);
00045 return res;
00046 }
00047
00048
00049 float getFloat(const std::string& in, int &c)
00050 {
00051 std::string tmp;
00052 eatws(in,c);
00053 while (c < (int)in.size() && get(in,c) != ' ' && get(in,c) != ')' && get(in,c) != ',') {
00054 tmp += get(in,c++);
00055 }
00056 eatws(in,c);
00057 return atof(tmp.c_str());
00058 }
00059
00060
00061 int getInt(const std::string& in, int &c)
00062 {
00063 std::string tmp;
00064 eatws(in,c);
00065 while (c < (int)in.size() && get(in,c) != ' ' && get(in,c) != ')' && get(in,c) != ',') {
00066 tmp += get(in,c++);
00067 }
00068 eatws(in,c);
00069 return atoi(tmp.c_str());
00070 }
00071
00072
00073 CNAlt getCNAlt(const std::string& in, int &c)
00074 {
00075 if (get(in,c++) != '(') {
00076 std::cerr << "PCN/PLF parse error: expected ( at start of cn alt block\n";
00077 return CNAlt();
00078 }
00079 std::string word = getEscapedString(in,c);
00080 if (get(in,c++) != ',') {
00081 std::cerr << "PCN/PLF parse error: expected , after string\n";
00082 return CNAlt();
00083 }
00084 size_t cnNext = 1;
00085 std::vector<float> probs;
00086 probs.push_back(getFloat(in,c));
00087 while (get(in,c) == ',') {
00088 c++;
00089 float val = getFloat(in,c);
00090 probs.push_back(val);
00091 }
00092
00093 if (probs.size()>1) {
00094 cnNext = static_cast<size_t>(probs.back());
00095 probs.pop_back();
00096 if (cnNext < 1) {
00097 ;
00098 std::cerr << "PCN/PLF parse error: bad link length at last element of cn alt block\n";
00099 return CNAlt();
00100 }
00101 }
00102 if (get(in,c++) != ')') {
00103 std::cerr << "PCN/PLF parse error: expected ) at end of cn alt block\n";
00104 return CNAlt();
00105 }
00106 eatws(in,c);
00107 return CNAlt(std::pair<std::string, std::vector<float> >(word,probs), cnNext);
00108 }
00109
00110
00111 CNCol getCNCol(const std::string& in, int &c)
00112 {
00113 CNCol res;
00114 if (get(in,c++) != '(') return res;
00115 eatws(in,c);
00116 while (1) {
00117 if (c > (int)in.size()) {
00118 break;
00119 }
00120 if (get(in,c) == ')') {
00121 c++;
00122 eatws(in,c);
00123 break;
00124 }
00125 if (get(in,c) == ',' && get(in,c+1) == ')') {
00126 c+=2;
00127 eatws(in,c);
00128 break;
00129 }
00130 if (get(in,c) == ',') {
00131 c++;
00132 eatws(in,c);
00133 }
00134 res.push_back(getCNAlt(in, c));
00135 }
00136 return res;
00137 }
00138
00139
00140 CN parsePCN(const std::string& in)
00141 {
00142 CN res;
00143 int c = 0;
00144 if (in[c++] != '(') return res;
00145 while (1) {
00146 if (c > (int)in.size()) {
00147 break;
00148 }
00149 if (get(in,c) == ')') {
00150 c++;
00151 eatws(in,c);
00152 break;
00153 }
00154 if (get(in,c) == ',' && get(in,c+1) == ')') {
00155 c+=2;
00156 eatws(in,c);
00157 break;
00158 }
00159 if (get(in,c) == ',') {
00160 c++;
00161 eatws(in,c);
00162 }
00163 res.push_back(getCNCol(in, c));
00164 }
00165 return res;
00166 }
00167
00168
00169 }
00170