24 #include "utap/sbmlconverter.h" 29 #include <libxml/xmlreader.h> 30 #include <libxml/xpath.h> 31 #include <libxml/parser.h> 32 #include <libxml/xmlstring.h> 47 using std::ostringstream;
81 const char *p = str.c_str();
83 if (!isspace((
unsigned char)*p)) {
92 return isalpha(c) || c ==
'_';
96 return isalnum(c) || c ==
'_' || c ==
'$' || c ==
'#';
109 throw "Identifier expected";
111 while (isspace((
unsigned char)*str)) {
115 throw "Identifier expected";
118 throw "Invalid identifier";
120 const char *end = str;
123 while (isspace((
unsigned char)*p)) {
127 throw "Invalid identifier";
129 return string(str, end - str);
137 bool operator()(
const xmlChar* x,
const xmlChar * y)
const {
138 return (strcmp((
const char*) x, (
const char*) y) < 0);
151 list<vector<tag_t> > path;
160 path.push_back(vector<tag_t > ());
163 void Path::push(
tag_t tag) {
164 path.back().push_back(tag);
165 path.push_back(vector<tag_t > ());
170 return path.back().back();
174 string Path::get(
tag_t tag)
const {
176 list<vector<tag_t> >::const_iterator i;
177 for (i = path.begin(); !i->empty() && i != path.end(); i++) {
186 str <<
"/declaration";
189 str <<
"/template[" <<
193 str <<
"/instantiation";
206 << std::count(i->begin(), i->end(),
TAG_LOCATION) <<
"]";
209 str <<
"/branchpoint[" 216 str <<
"/transition[" <<
221 std::count(i->begin(), i->end(),
TAG_LABEL) <<
"]";
237 << std::count(i->begin(), i->end(),
TAG_NAIL) <<
"]";
243 str <<
"/lscTemplate[" <<
244 std::count(i->begin(), i->end(),
TAG_LSC) <<
"]";
253 str <<
"/ylocoord[" <<
257 str <<
"/lsclocation";
264 << std::count(i->begin(), i->end(),
TAG_INSTANCE) <<
"]";
267 str <<
"/temperature[" 272 << std::count(i->begin(), i->end(),
TAG_MESSAGE) <<
"]";
280 << std::count(i->begin(), i->end(),
TAG_UPDATE) <<
"]";
284 << std::count(i->begin(), i->end(),
TAG_ANCHOR) <<
"]";
288 << std::count(i->begin(), i->end(),
TAG_SBML) <<
"]";
295 << std::count(i->begin(), i->end(),
TAG_QUERY) <<
"]";
302 throw std::logic_error(
"XPath is corrupted");
304 if (i->back() == tag) {
317 typedef map<xmlChar*, string, compare_str> elementmap_t;
319 xmlTextReaderPtr reader;
333 bool begin(
tag_t,
bool skipEmpty =
true);
336 const string getName(
const xmlChar *
id);
340 bool label(
bool required =
false,
string kind =
"");
347 string name(
bool instanceLine =
false);
348 string readString(
tag_t tag,
bool instanceLine =
false);
349 string readText(
bool instanceLine =
false);
356 bool instantiation();
358 string reference(
string attributeName);
363 vector<char*> anchors();
367 string temperature();
383 xmlTextReaderPtr reader,
ParserBuilder *parser,
bool newxta);
384 virtual ~XMLReader();
388 XMLReader::XMLReader(
390 : reader(reader), parser(parser), newxta(newxta) {
394 XMLReader::~XMLReader() {
395 elementmap_t::iterator i;
396 for (i = names.begin(); i != names.end(); ++i) {
399 xmlFreeTextReader(reader);
403 int XMLReader::getNodeType() {
404 return xmlTextReaderNodeType(reader);
411 tag_t XMLReader::getElement() {
412 const char *element = (
const char *) xmlTextReaderConstLocalName(reader);
413 const Tag *tag = Tags::in_word_set(element, strlen(element));
416 throw std::runtime_error(
"Unknown tag in XML file");
422 bool XMLReader::isEmpty() {
423 return xmlTextReaderIsEmptyElement(reader);
431 bool XMLReader::begin(
tag_t tag,
bool skipEmpty) {
433 while (getNodeType() != XML_READER_TYPE_ELEMENT) {
436 if (getElement() != tag) {
440 if (!skipEmpty || !isEmpty()) {
454 while (getNodeType() == XML_READER_TYPE_WHITESPACE
455 || getNodeType() == XML_READER_TYPE_SIGNIFICANT_WHITESPACE) {
459 return getNodeType() == XML_READER_TYPE_END_ELEMENT && getElement() == tag;
465 if ((getNodeType() == XML_READER_TYPE_END_ELEMENT)
466 || (getNodeType() == XML_READER_TYPE_ELEMENT && isEmpty())) {
467 if (path.pop() != getElement()) {
469 throw std::runtime_error(
"Invalid nesting in XML document");
472 if (xmlTextReaderRead(reader) != 1) {
474 throw std::runtime_error(
"Unexpected end of XML document");
477 if (getNodeType() == XML_READER_TYPE_ELEMENT) {
478 path.push(getElement());
483 const string XMLReader::getName(
const xmlChar *
id) {
485 elementmap_t::iterator l = names.find((xmlChar*)
id);
486 if (l != names.end()) {
490 throw std::runtime_error(
"Missing reference");
495 return parseXTA((
const char*) text, parser, newxta, syntax, path.get());
499 bool XMLReader::declaration() {
502 if (getNodeType() == XML_READER_TYPE_TEXT) {
511 bool XMLReader::label(
bool required,
string s_kind) {
516 kind = xmlTextReaderGetAttribute(reader, (
const xmlChar *)
"kind");
520 if (getNodeType() == XML_READER_TYPE_TEXT) {
521 const xmlChar *text = xmlTextReaderConstValue(reader);
523 if (strcmp((
char*) kind,
"invariant") == 0) {
525 }
else if (strcmp((
char*) kind,
"select") == 0) {
527 }
else if (strcmp((
char*) kind,
"guard") == 0) {
529 }
else if (strcmp((
char*) kind,
"synchronisation") == 0) {
531 }
else if (strcmp((
char*) kind,
"assignment") == 0) {
533 }
else if (strcmp((
char*) kind,
"probability") == 0) {
535 }
else if (strcmp((
char*) kind,
"message") == 0)
538 }
else if (strcmp((
char*) kind,
"update") == 0)
541 }
else if (strcmp((
char*) kind,
"condition") == 0)
548 }
else if (required) {
550 if (strcmp(s_kind.c_str(),
"message") == 0)
552 else if (strcmp(s_kind.c_str(),
"update") == 0)
554 else if (strcmp(s_kind.c_str(),
"condition") == 0)
555 parser->
handleError(
"$Condition_label_is_required");
560 int XMLReader::invariant() {
566 kind = xmlTextReaderGetAttribute(reader, (
const xmlChar *)
"kind");
570 if (getNodeType() == XML_READER_TYPE_TEXT) {
571 const xmlChar *text = xmlTextReaderConstValue(reader);
576 if (strcmp((
char*) kind,
"invariant") == 0) {
580 }
else if (strcmp((
char*) kind,
"exponentialrate") == 0) {
592 string XMLReader::name(
bool instanceLine) {
593 string text = readString(
TAG_NAME, instanceLine);
594 if (instanceLine && strcmp(text.c_str(),
"") == 0)
599 string XMLReader::readText(
bool instanceLine) {
600 if (getNodeType() == XML_READER_TYPE_TEXT)
602 xmlChar *text = xmlTextReaderValue(reader);
606 string id = (instanceLine) ? (
char*) text :
symbol((
char*) text);
611 parser->
handleError(
"$Keywords_are_not_allowed_here");
612 }
catch (
const char *str) {
620 int XMLReader::readNumber() {
622 if (getNodeType() == XML_READER_TYPE_TEXT)
624 xmlChar *text = xmlTextReaderValue(reader);
628 string id = (
char*) text;
630 return atoi(
id.c_str());
631 }
catch (
const char *str) {
639 string XMLReader::readString(
tag_t tag,
bool instanceLine) {
642 return readText(instanceLine);
648 string XMLReader::type() {
653 string XMLReader::mode() {
660 int XMLReader::lscLocation() {
666 throw std::runtime_error(
"Missing LSC location");
671 bool XMLReader::committed() {
680 bool XMLReader::urgent() {
689 bool XMLReader::location() {
691 xmlChar *l_id = NULL;
692 bool l_committed =
false;
693 bool l_urgent =
false;
694 bool l_invariant =
false;
695 bool l_exponentialRate =
false;
703 l_id = xmlTextReaderGetAttribute(reader, (
const xmlChar*)
"id");
714 int res = invariant();
715 l_invariant |= res == 0;
716 l_exponentialRate |= res == 1;
722 l_committed = committed();
730 l_name = string(
"_") + (
char*) l_id;
735 names[l_id] = l_name;
747 parser->
procState(l_name.c_str(), l_invariant, l_exponentialRate);
763 bool XMLReader::instance() {
765 xmlChar *i_id = NULL;
773 i_id = xmlTextReaderGetAttribute(reader, (
const xmlChar*)
"id");
785 names[i_id] = i_name;
808 bool XMLReader::yloccoord() {
816 string XMLReader::temperature() {
823 throw std::runtime_error(
"Missing temperature");
826 bool XMLReader::prechart() {
834 bottomPrechart = lscLocation();
835 if (strcasecmp(currentType.c_str(),
"existential") == 0) {
838 parser->
handleError(
"$Existential_charts_must_not_have_prechart");
852 bool XMLReader::message() {
865 location = lscLocation();
866 bool pch = (location < bottomPrechart);
869 parser->
procMessage(from.c_str(), to.c_str(), location, pch);
872 label(
true,
"message");
882 bool XMLReader::condition() {
884 vector<char*> instance_anchors;
893 instance_anchors = anchors();
894 location = lscLocation();
895 pch = (location < bottomPrechart);
899 temp = temperature();
900 hot = (temp ==
"hot");
903 label(
true,
"condition");
913 bool XMLReader::update() {
915 string instance_anchor;
925 instance_anchor = anchor();
926 location = lscLocation();
927 pch = (location < bottomPrechart);
931 parser->
procLscUpdate(instance_anchor.c_str(), location, pch);
932 label(
true,
"update");
943 bool XMLReader::branchpoint() {
945 xmlChar *b_id = NULL;
954 b_id = xmlTextReaderGetAttribute(reader, (
const xmlChar*)
"id");
961 b_name = string(
"_") + (
char*) b_id;
965 names[b_id] = b_name;
991 bool XMLReader::init() {
995 xmlChar *ref = xmlTextReaderGetAttribute(reader, (
const xmlChar*)
"ref");
1000 string name = getName(ref);
1018 string XMLReader::reference(
string attributeName) {
1020 xmlChar *
id = xmlTextReaderGetAttribute(reader, (
const xmlChar*) attributeName.c_str());
1028 string XMLReader::source() {
1030 return reference(
"ref");
1031 throw std::runtime_error(
"Missing source element");
1035 string XMLReader::target() {
1037 return reference(
"ref");
1038 throw std::runtime_error(
"Missing target element");
1042 string XMLReader::anchor() {
1044 return reference(
"instanceid");
1045 throw std::runtime_error(
"Missing anchor element");
1049 vector<char*> XMLReader::anchors() {
1050 vector<char*> names;
1052 string name = reference(
"instanceid");
1053 names.push_back(const_cast<char*> (name.c_str()));
1056 if (names.size() == 0)
1057 throw std::runtime_error(
"Missing anchor element");
1062 bool XMLReader::transition() {
1066 bool control =
true;
1073 xmlTextReaderGetAttribute(reader, (
const xmlChar*)
"controllable");
1074 control = (type == NULL || !(strcmp((
char*) type,
"true")));
1077 xmlChar *
id = xmlTextReaderGetAttribute(reader, (
const xmlChar*)
"action");
1079 actname = (
char *)
id;
1089 parser->
procEdgeBegin(from.c_str(), to.c_str(), control, actname.c_str());
1108 int XMLReader::parameter() {
1112 if (getNodeType() == XML_READER_TYPE_TEXT) {
1113 count = parse(xmlTextReaderConstValue(reader),
S_PARAMETERS);
1120 bool XMLReader::templ() {
1144 while (branchpoint());
1148 while (transition());
1165 bool XMLReader::lscTempl() {
1169 string t_path = path.get(
TAG_LSC);
1178 currentType = type();
1180 currentMode = mode();
1187 parser->
procBegin(t_name.c_str(),
false, currentType, currentMode);
1194 while (yloccoord());
1202 while (condition());
1220 bool XMLReader::instantiation() {
1222 const xmlChar *text = (
const xmlChar*)
"";
1224 if (getNodeType() == XML_READER_TYPE_TEXT) {
1225 text = xmlTextReaderConstValue(reader);
1234 void XMLReader::system() {
1236 const xmlChar *text = (
const xmlChar*)
"";
1238 if (getNodeType() == XML_READER_TYPE_TEXT) {
1239 text = xmlTextReaderConstValue(reader);
1252 bool XMLReader::queries() {
1261 bool XMLReader::query() {
1273 bool XMLReader::formula(){
1277 parser->
queryFormula((
const char*)xmlTextReaderConstValue(reader),
1284 if (begin(TAG_COMMENT,
false)){
1286 parser->
queryComment((
const char*)xmlTextReaderConstValue(reader));
1293 void XMLReader::project() {
1298 UTAP::SBMLConverter * sbmlc =
new SBMLConverter(reader);
1299 sbmlc->convertIntoXML();
1302 throw std::runtime_error(
"Missing nta or project element");
1307 nta = (begin(
TAG_NTA)) ?
true :
false;
1323 using namespace UTAP;
1327 xmlTextReaderPtr reader = xmlReaderForFile(filename,
"",
1328 XML_PARSE_NOCDATA | XML_PARSE_NOBLANKS | XML_PARSE_HUGE | XML_PARSE_RECOVER);
1329 if (reader == NULL) {
1332 XMLReader(reader, pb, newxta).project();
1337 size_t length = strlen(buffer);
1338 xmlTextReaderPtr reader = xmlReaderForMemory(buffer, length,
"",
"",
1339 XML_PARSE_NOCDATA | XML_PARSE_HUGE | XML_PARSE_RECOVER);
1340 if (reader == NULL) {
1343 XMLReader(reader, pb, newxta).project();
1358 xmlXPathContextPtr context = xmlXPathNewContext(docPtr);
1359 if(context == NULL) {
1364 xmlXPathObjectPtr result = xmlXPathEvalExpression((xmlChar*)path.c_str(), context);
1366 xmlNodeSetPtr nodeset = result->nodesetval;
1367 if(!xmlXPathNodeSetIsEmpty(nodeset) && nodeset->nodeNr>0) {
1369 xmlNodePtr node = nodeset->nodeTab[0];
1370 xmlChar *s = xmlNodeListGetString(docPtr, node->xmlChildrenNode, 1);
1376 xmlXPathFreeObject(result);
1379 xmlXPathFreeContext(context);
1391 xmlDocPtr docPtr = xmlParseMemory(xmlBuffer, strlen(xmlBuffer));
static void setPath(ParserBuilder *builder, std::string s)
Sets the current path to s, offset to 0 and line to 1.
virtual void procMessage(const char *from, const char *to, const int loc, const bool pch)=0
virtual void procStateUrgent(const char *name)=0
string getXMLElement(xmlDocPtr docPtr, const string &path)
Get the contents of the XML element with the specified path.
virtual void procLscUpdate(const char *anchor, const int loc, const bool pch)=0
virtual void procBranchpoint(const char *name)=0
virtual void procCondition(const std::vector< char *> anchors, const int loc, const bool pch, const bool hot)=0
virtual void procStateInit(const char *name)=0
virtual void procStateCommit(const char *name)=0
The ParserBuilder interface is used by the parser to output the parsed system.
xta_part_t
Type for specifying which XTA part to parse (syntax switch)
int32_t parseXMLFile(const char *filename, ParserBuilder *pb, bool newxta)
Parse the file with the given name assuming it is in the XML format, reporting the system to the give...
virtual void queryBegin()=0
Verification queries.
virtual void procBegin(const char *name, const bool isTA=true, const std::string type="", const std::string mode="")=0
static bool isempty(string str)
Returns TRUE if string is zero length or contains only white spaces otherwise FALSE.
virtual void queryFormula(const char *formula, const char *location)=0
virtual void queryEnd()=0
static bool isAlpha(unsigned char c)
int32_t parseXMLBuffer(const char *buffer, ParserBuilder *pb, bool newxta)
Parse a buffer in the XML format, reporting the system to the given implementation of the the ParserB...
static string symbol(const char *str)
Extracts the alpha-numerical symbol used for variable/type identifiers.
static bool isIdChr(unsigned char c)
tag_t
Enumeration type for tags.
virtual void handleError(const std::string &)=0
Exception indicating a type error.
virtual void queryComment(const char *comment)=0
bool read(istream &file, string &str)
virtual void procEdgeEnd(const char *from, const char *to)=0
static int32_t parseXTA(ParserBuilder *aParserBuilder, bool newxta, xta_part_t part, std::string xpath)
std::vector< std::string > lscTemplateNames
virtual void procInstanceLine()=0
virtual void hasPrechart(const bool pch)=0
bool isKeyword(const char *id, uint32_t syntax)
static int increment(ParserBuilder *builder, int n)
Sets the position of builder to [position, position + n) and increments position and offset by n...
virtual void procEdgeBegin(const char *from, const char *to, const bool control, const char *actname="")=0
virtual void procState(const char *name, bool hasInvariant, bool hasER)=0