00001
00002 #include "cafe/ParseRun.hpp"
00003
00004 #include <ctype.h>
00005 #include <stdexcept>
00006 #include <iostream>
00007 #include "cafe/Processor.hpp"
00008
00009 namespace cafe {
00010
00011 ParseRun::ParseRun()
00012 {}
00013
00014 void ParseRun::init(const std::string& input)
00015 {
00016 _input = input;
00017 _ptr = input.c_str();
00018 _ch = *_ptr;
00019 _ident.clear();
00020 }
00021
00022 bool ParseRun::next()
00023 {
00024 return (_ch = *++_ptr) != '\0';
00025 }
00026
00027 void ParseRun::skip_ws()
00028 {
00029 while(isspace(_ch) && next()) {}
00030 }
00031
00032 void ParseRun::ident()
00033 {
00034 _ident.clear();
00035
00036 while(isalnum(_ch) || (_ch == '_') || (_ch == ':')) {
00037 _ident += _ch;
00038 next();
00039 }
00040 }
00041
00042 cafe::Processor *ParseRun::def()
00043 {
00044 std::string class_name;
00045 std::string instance;
00046
00047 if(isalpha(_ch) || (_ch == '(')) {
00048 if(_ch == '(') {
00049 next();
00050 ident();
00051 class_name = "Group";
00052 instance = _ident;
00053 if(_ch != ')') {
00054 error(") expected");
00055 } else {
00056 next();
00057 }
00058 } else {
00059 ident();
00060 class_name = _ident;
00061 instance = _ident;
00062 skip_ws();
00063 if(_ch == '(') {
00064 next();
00065 skip_ws();
00066 ident();
00067 instance = _ident;
00068 skip_ws();
00069 if(_ch != ')') {
00070 error(") expected");
00071 }
00072 next();
00073 }
00074 }
00075 return Processor::Create(class_name, instance);
00076 } else {
00077 error("Identifier expected");
00078 return 0;
00079 }
00080 }
00081
00082 std::list<Processor*> ParseRun::parse(const std::string& input)
00083 {
00084 init(input);
00085
00086 std::list<Processor*> result;
00087
00088 skip_ws();
00089 while(Processor *p = def()) {
00090 result.push_back(p);
00091
00092 while(_ch == ',' || isspace(_ch)) {
00093 next();
00094 }
00095 if(_ch == '\0') break;
00096 }
00097 return result;
00098 }
00099
00100 void ParseRun::error(const char *msg)
00101 {
00102 std::cerr << "ParseRun: Error at " << _ptr - _input.c_str() << " : " << msg << std::endl;
00103 throw std::runtime_error("Parse Error in Run specification");
00104 }
00105 }
00106