1 parent
14e45e9cb4
commit
80d462a8c2
17 files changed
+789
-238
No files matched your search
@@ -24,6 +24,7 @@ class div_zero_exception_t : public exception_t {
|
||||
};
|
||||
|
||||
typedef uint64_t args_t;
|
||||
static const args_t ARGS_MAX = UINT64_MAX;
|
||||
typedef std::map<std::string, args_t> args_map_t;
|
||||
class Expr;
|
||||
|
||||
@@ -177,14 +178,19 @@ class Expr {
|
||||
bool SubCheck() const { return (sub_count_ == 0); }
|
||||
unsigned FindOp() const {
|
||||
unsigned i = pos_;
|
||||
unsigned open_n = 0;
|
||||
while (i < expr_.length()) {
|
||||
switch (Symb(i)) {
|
||||
case '*':
|
||||
case '/':
|
||||
case '+':
|
||||
case '-':
|
||||
goto end;
|
||||
case '(':
|
||||
++open_n;
|
||||
break;
|
||||
case ')':
|
||||
if (open_n != 0) i += 1;
|
||||
goto end;
|
||||
}
|
||||
++i;
|
||||
@@ -263,6 +269,74 @@ class var_expr_t : public bin_expr_t {
|
||||
const std::string name_;
|
||||
};
|
||||
|
||||
class fun_expr_t : public bin_expr_t {
|
||||
public:
|
||||
typedef std::vector<var_expr_t> vvect_t;
|
||||
fun_expr_t(const std::string& fname, const std::string& vname, const uint32_t& vnum) : fname_(fname) {
|
||||
for (uint32_t i = 0; i < vnum; ++i) {
|
||||
std::ostringstream var_full_name;
|
||||
var_full_name << vname << "[" << i << "]";
|
||||
vvect.push_back(var_expr_t(var_full_name.str()));
|
||||
}
|
||||
}
|
||||
const vvect_t& GetVars() const { return vvect; }
|
||||
std::string Symbol() const {
|
||||
const std::string var = vvect[0].Symbol();
|
||||
const std::string vname = var.substr(0, var.length() - 3);
|
||||
std::ostringstream oss;
|
||||
std::string str("(");
|
||||
str.back() = ')';
|
||||
oss << fname_ << "(" << vname << "," << vvect.size() << ")";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
private:
|
||||
const std::string fname_;
|
||||
vvect_t vvect;
|
||||
};
|
||||
class sum_expr_t : public fun_expr_t {
|
||||
public:
|
||||
sum_expr_t(const std::string& vname, const uint32_t& vnum) : fun_expr_t("sum", vname, vnum) {}
|
||||
args_t Eval(const args_cache_t& args) const {
|
||||
args_t result = 0;
|
||||
for (const auto& var : GetVars()) result += var.Eval(args);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
class avr_expr_t : public fun_expr_t {
|
||||
public:
|
||||
avr_expr_t(const std::string& vname, const uint32_t& vnum) : fun_expr_t("avr", vname, vnum) {}
|
||||
args_t Eval(const args_cache_t& args) const {
|
||||
args_t result = 0;
|
||||
for (const auto& var : GetVars()) result += var.Eval(args);
|
||||
return result / GetVars().size();
|
||||
}
|
||||
};
|
||||
class min_expr_t : public fun_expr_t {
|
||||
public:
|
||||
min_expr_t(const std::string& vname, const uint32_t& vnum) : fun_expr_t("min", vname, vnum) {}
|
||||
args_t Eval(const args_cache_t& args) const {
|
||||
args_t result = ARGS_MAX;
|
||||
for (const auto& var : GetVars()) {
|
||||
args_t val = var.Eval(args);
|
||||
result = (val < result) ? val : result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
class max_expr_t : public fun_expr_t {
|
||||
public:
|
||||
max_expr_t(const std::string& vname, const uint32_t& vnum) : fun_expr_t("max", vname, vnum) {}
|
||||
args_t Eval(const args_cache_t& args) const {
|
||||
args_t result = 0;
|
||||
for (const auto& var : GetVars()) {
|
||||
args_t val = var.Eval(args);
|
||||
result = (val > result) ? val : result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
inline const bin_expr_t* bin_expr_t::CreateExpr(const bin_expr_t* arg1, const bin_expr_t* arg2,
|
||||
const char op) {
|
||||
const bin_expr_t* expr = NULL;
|
||||
@@ -285,11 +359,41 @@ inline const bin_expr_t* bin_expr_t::CreateExpr(const bin_expr_t* arg1, const bi
|
||||
|
||||
inline const bin_expr_t* bin_expr_t::CreateArg(Expr* obj, const std::string str) {
|
||||
const bin_expr_t* arg = NULL;
|
||||
|
||||
const unsigned i = strspn(str.c_str(), "1234567890");
|
||||
if (i == str.length()) {
|
||||
const unsigned value = atoi(str.c_str());
|
||||
arg = new const_expr_t(value);
|
||||
} else {
|
||||
}
|
||||
|
||||
if (arg == NULL) {
|
||||
const std::size_t pos = str.find('(');
|
||||
if (pos != std::string::npos) {
|
||||
char* fname = NULL;
|
||||
char* vname = NULL;
|
||||
int vnum = 0;
|
||||
int ret = sscanf(str.c_str(), "%m[a-zA-Z_](%m[0-9a-zA-Z_],%d)", &fname, &vname, &vnum);
|
||||
if (ret == 3) {
|
||||
const std::string fun_name(fname);
|
||||
const fun_expr_t* farg = NULL;
|
||||
if (fun_name == "sum") {
|
||||
farg = new sum_expr_t(vname, vnum);
|
||||
} else if (fun_name == "avr") {
|
||||
farg = new avr_expr_t(vname, vnum);
|
||||
} else if (fun_name == "min") {
|
||||
farg = new min_expr_t(vname, vnum);
|
||||
} else if (fun_name == "max") {
|
||||
farg = new max_expr_t(vname, vnum);
|
||||
}
|
||||
if (farg) for (const auto& var : farg->GetVars()) obj->AddVar(var.Symbol());
|
||||
arg = farg;
|
||||
}
|
||||
free(fname);
|
||||
free(vname);
|
||||
}
|
||||
}
|
||||
|
||||
if (arg == NULL) {
|
||||
const std::string sub_expr = obj->Lookup(str);
|
||||
if (sub_expr.empty()) {
|
||||
arg = new var_expr_t(str);
|
||||
@@ -299,6 +403,7 @@ inline const bin_expr_t* bin_expr_t::CreateArg(Expr* obj, const std::string str)
|
||||
arg = expr->GetTree();
|
||||
}
|
||||
}
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,11 +36,29 @@ class Xml {
|
||||
return xml;
|
||||
}
|
||||
|
||||
void AddExpr(const std::string& full_tag, const std::string& name, const std::string& expr) {
|
||||
const std::size_t pos = full_tag.rfind('.');
|
||||
const std::size_t pos1 = (pos == std::string::npos) ? 0 : pos + 1;
|
||||
const std::string level_tag = full_tag.substr(pos1);
|
||||
level_t* level = new level_t;
|
||||
map_[full_tag].push_back(level);
|
||||
level->tag = level_tag;
|
||||
level->opts["name"] = name;
|
||||
level->opts["expr"] = expr;
|
||||
}
|
||||
|
||||
void AddConst(const std::string& full_tag, const std::string& name, const uint64_t& val) {
|
||||
std::ostringstream oss;
|
||||
oss << val;
|
||||
AddExpr(full_tag, name, oss.str());
|
||||
}
|
||||
|
||||
static void Destroy(Xml *xml) { delete xml; }
|
||||
|
||||
std::vector<level_t*> GetNodes(std::string global_tag) { return map_[global_tag]; }
|
||||
|
||||
void Print() const {
|
||||
std::cout << "XML file '" << file_name_ << "':" << std::endl;
|
||||
for (auto& elem : map_) {
|
||||
for (auto node : elem.second) {
|
||||
if (node->opts.size()) {
|
||||
@@ -74,13 +92,14 @@ class Xml {
|
||||
while (1) {
|
||||
token_t token = (remainder.size()) ? remainder : NextToken();
|
||||
remainder.clear();
|
||||
|
||||
// token_t token1 = token;
|
||||
// token1.push_back('\0');
|
||||
// std::cout << "> " << &token1[0] << std::endl;
|
||||
|
||||
// End of file
|
||||
if (token.size() == 0) break;
|
||||
|
||||
// token_t token1 = token;
|
||||
// token1.push_back('\0');
|
||||
// std::cout << "> " << &token1[0] << std::endl;
|
||||
|
||||
switch (state_) {
|
||||
case BODY_STATE:
|
||||
if (token[0] == '<') {
|
||||
@@ -146,6 +165,11 @@ class Xml {
|
||||
|
||||
~Xml() {}
|
||||
|
||||
bool SpaceCheck() const {
|
||||
bool cond = ((buffer_[index_] == ' ') || (buffer_[index_] == ' '));
|
||||
return cond;
|
||||
}
|
||||
|
||||
bool LineEndCheck() {
|
||||
bool found = false;
|
||||
if (buffer_[index_] == '\n') {
|
||||
@@ -162,24 +186,55 @@ class Xml {
|
||||
|
||||
token_t NextToken() {
|
||||
token_t token;
|
||||
bool in_string = false;
|
||||
bool special_symb = false;
|
||||
|
||||
while (1) {
|
||||
if (data_size_ == 0) {
|
||||
data_size_ = read(fd_, buffer_, buf_size_);
|
||||
if (data_size_ <= 0) break;
|
||||
}
|
||||
|
||||
if (token.empty())
|
||||
while ((index_ < data_size_) && ((buffer_[index_] == ' ') || LineEndCheck())) {
|
||||
while ((index_ < data_size_) && (SpaceCheck() || LineEndCheck())) {
|
||||
++index_;
|
||||
}
|
||||
while ((index_ < data_size_) && (buffer_[index_] != ' ') && !LineEndCheck()) {
|
||||
token.push_back(buffer_[index_++]);
|
||||
while ((index_ < data_size_) && (in_string || !(SpaceCheck() || LineEndCheck()))) {
|
||||
const char symb = buffer_[index_];
|
||||
bool skip_symb = false;
|
||||
|
||||
switch (symb) {
|
||||
case '\\':
|
||||
if (special_symb) special_symb = false;
|
||||
else {
|
||||
special_symb = true;
|
||||
skip_symb = true;
|
||||
}
|
||||
break;
|
||||
case '"':
|
||||
if (special_symb) special_symb = false;
|
||||
else {
|
||||
in_string = !in_string;
|
||||
if (!in_string) {
|
||||
buffer_[index_] = ' ';
|
||||
--index_;
|
||||
}
|
||||
skip_symb = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!skip_symb) token.push_back(symb);
|
||||
++index_;
|
||||
}
|
||||
|
||||
if (index_ == data_size_) {
|
||||
index_ = 0;
|
||||
data_size_ = 0;
|
||||
} else
|
||||
} else {
|
||||
if (special_symb || in_string) BadFormat(token);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return token;
|
||||
|
||||
Reference in new issue
Block a user