Files
secondo/Algebras/CStream/VTree.cpp

330 lines
8.0 KiB
C++
Raw Normal View History

2026-01-23 17:03:45 +08:00
/*
----
This file is part of SECONDO.
Copyright (C) 2004, University in Hagen, Department of Computer Science,
Database Systems for New Applications.
SECONDO is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
SECONDO is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with SECONDO; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
----
//paragraph [1] Title: [{\Large \bf \begin{center}] [\end{center}}]
//characters [1] Type: [] []
//characters [2] Type: [] []
//[ae] [\"{a}]
//[oe] [\"{o}]
//[ue] [\"{u}]
//[ss] [{\ss}]
//[Ae] [\"{A}]
//[Oe] [\"{O}]
//[Ue] [\"{U}]
//[x] [$\times $]
//[->] [$\rightarrow $]
//[toc] [\tableofcontents]
[1] Implementation of VTree.
[toc]
1 Node class implementation
2 VTree class implementation
*/
#include "VTree.h"
#include "VTHelpers.h"
#include <iostream>
namespace cstream {
static std::string cerror = "TupleDescr: wrong Format at pos: ";
/*
1.1 Constructor
*/
Node::Node( const std::string& n,
const std::string& t,
Node* p) : _parent(p) {
_name = n;
_type = t;
}
/*
1.2 AddChild
*/
void Node:: AddChild(Node* p) {
_children.push_back(p);
}
/*
2.1 IsLetterDigit
Checks if a character is letter or digit
*/
bool VTree::IsLetterDigit(char ch) {
if (ch >= 'a' && ch <= 'z')
return true;
if (ch >= 'A' && ch <= 'Z')
return true;
if (ch >= '0' && ch <= '9')
return true;
return false;
}
/*
2.2 EatSpace
Removes spaces from starting at position pos of a string.
*/
bool VTree::EatSpace(const std::string& s, size_t& pos) {
while (pos < s.length() && s[pos] == ' ') {
pos++;
if (pos >= s.length())
return false;
}
return true;
}
/*
2.3 GetNextSpace
Finds the 1st position of space from the beginning in a string.
*/
size_t VTree::GetNextSpace(const std::string& s, size_t pos,
bool& nospace) {
do {
if (pos >= s.size())
return -1;
if (s[pos] == '(' || s[pos] == ')') {
nospace = true;
return pos;
}
} while (s[pos++] != ' ');
nospace = false;
return pos-1;
}
/*
2.4 NextCloseBracket
Finds the next close bracket. Allowed chars before the ')'
are letters, digits or spaces.
*/
size_t VTree::NextCloseBracket(const std::string& s, size_t pos) {
do {
if (pos >= s.size())
return -1;
if (s[pos] == ')')
return pos;
if (!IsLetterDigit(s[pos]) && s[pos] != ' ')
return -1;
pos++;
} while (true);
return -1;
}
/*
2.5 NextOpenBracket
Finds the next open bracket. Allowed chars before the '('
are letters, digits or spaces.
*/
size_t VTree::NextOpenBracket(const std::string& s, size_t pos) {
do {
if (pos >= s.size())
return -1;
if (s[pos] == '(')
return pos;
if (!IsLetterDigit(s[pos]) && s[pos] != ' ')
return -1;
pos++;
} while (true);
return -1;
}
/*
2.6 RemoveSpace
Removes spaces at the beginning and end of a string.
*/
void VTree::RemoveSpace(std::string& s) {
while (s.length() > 0 && s[0] == ' ') {
s = s.substr(1, s.size() - 1);
}
while (s.length() > 0 && s[s.length()-1] == ' ') {
s = s.substr(0, s.size() - 1);
}
}
/*
2.7 CreateRec
Constructs the expression tree, recursive part.
*/
void VTree::CreateRec(
Node* parent,
const ListExpr& list,
int depth,
bool isvector,
std::string& error
) {
if (!error.empty())
return;
std::set<std::string> attr_names;
ListExpr rest = list;
while (!nl->IsEmpty(rest)) {
std::string sattrname;
ListExpr attrtype;
if (!isvector) {
ListExpr attr = nl->First(rest);
rest = nl->Rest(rest);
if (nl->ListLength(attr) < 2) {
error = "TupleDescr: invalid attr pair: " +
nl->ToString(attr);
return;
}
ListExpr attrname = nl->First(attr);
attrtype = nl->Rest(attr);
// check attr name here!
std::string error_name;
if (!listutils::isValidAttributeName(attrname, error_name)) {
error = "TupleDescr: " + error_name;
return;
}
// check for duplicate names
sattrname = nl->SymbolValue(attrname);
if(attr_names.find(sattrname) != attr_names.end()) {
error = "TupleDescr: duplicate attr name: " + sattrname;
return;
}
attr_names.insert(sattrname);
attrtype = nl->First(attrtype);
} else {
attrtype = list;
rest = nl->TheEmptyList();
}
int typelen = nl->ListLength(attrtype);
if (typelen <= 0) {
std::string sattrtype = nl->ToString(attrtype);
ListExpr errorinfo = listutils::emptyErrorInfo();
if (!am->CheckKind(Kind::DATA(), attrtype, errorinfo)) {
error = "TupleDescr: attr type error: " +
nl->ToString(errorinfo);
return;
}
Node* node = new Node(sattrname, sattrtype, parent);
_num_nodes++;
parent->AddChild(node);
} else { // complex type, record or vector
ListExpr attrtype1 = nl->First(attrtype);
std::string sattrtype = nl->ToString(attrtype1);
ListExpr errorinfo = listutils::emptyErrorInfo();
if (!am->CheckKind(Kind::DATA(), attrtype, errorinfo)) {
error = "TupleDescr: attr type error: " +
nl->ToString(errorinfo);
return;
}
Node* node = new Node(sattrname, sattrtype, parent);
_num_nodes++;
parent->AddChild(node);
ListExpr attrlist = nl->Rest(attrtype);
if (sattrtype == "vector")
{
attrtype = nl->First(attrlist);
if (!am->CheckKind(Kind::DATA(), attrtype, errorinfo)) {
error = "TupleDescr: attr type error: " +
nl->ToString(errorinfo);
return;
}
// recursive descend here for vector
CreateRec(node, attrtype, depth+1, true, error);
} else {
// recursive descend here
CreateRec(node, attrlist, depth+1, false, error);
}
}
}
}
/*
2.8 Create
Constructs the expression tree.
*/
Node* VTree::Create(
ListExpr list,
std::string& error,
int& max_depth,
int& num_nodes
) {
_max_depth = 0;
Node* root = new Node("ROOT", "ROOT", NULL);
_num_nodes = 1;
error = "";
CreateRec(root, list, 0, false, error);
max_depth = _max_depth;
num_nodes = _num_nodes;
return root;
}
/*
2.9 DeleteRec
Delete the tree, recursive part.
*/
void VTree::DeleteRec(Node* n) {
for (std::vector<Node*>::iterator it = n->_children.begin();
it != n->_children.end(); ++it) {
DeleteRec(*it);
}
delete n;
n = NULL;
}
/*
2.10 Delete
Deletes the tree.
*/
void VTree::Delete(Node*& root) {
DeleteRec(root);
root = NULL;
}
/*
2.11 Print
Prints the tree to cout.
*/
void VTree::Print(Node* n, const std::string& ident) {
std::cout << ident << "(" << n->_name <<
" " << n->_type << ")" << std::endl;
for (std::vector<Node*>::iterator it = n->_children.begin();
it != n->_children.end(); ++it) {
Print(*it, ident + "____");
}
}
} /* namespace cstream */