Skip to content

Commit 1035f0f

Browse files
committed
- fix bug with contexts and regexp mathcing nothing
- introduce None context to match start and end of string - fix bug with parsing of rule header - introduce matching of [ in left context to match branching relation - first draft of lpyimort (very xperimnetal) git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/vplants/vplants/trunk/lpy@13750 ab253cce-29fb-0310-bb2f-979600cdbdeb
1 parent 77726d4 commit 1035f0f

21 files changed

+507
-63
lines changed

src/cpp/lpy_parser.cpp

+44-15
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,30 @@ Lsystem::set( const std::string& _rules , std::string * pycode,
488488
}
489489
else toendlineA(_it,endpycode);
490490
break;
491+
case 'l':
492+
_it2 = _it;
493+
if(has_keyword_pattern(_it,begcode,endpycode,"lpyimport")){
494+
code+=std::string(beg,_it2);
495+
beg = _it;
496+
if(_it!=endpycode){
497+
_it++;
498+
beg = _it;
499+
toendline(_it,endpycode);
500+
if(beg != endpycode) {
501+
if (notOnlySpace(beg,_it)){
502+
std::string modulename = LpyParsing::trim(std::string(beg,_it));
503+
addSubLsystem(modulename+".lpy");
504+
}
505+
else LsysParserSyntaxError("invalid module to import");
506+
}
507+
else LsysParserSyntaxError("invalid module to import");
508+
}
509+
else LsysParserSyntaxError("invalid module to import");
510+
code+="# "+std::string(_it2,_it);
511+
beg = _it;
512+
}
513+
else toendlineA(_it,endpycode);
514+
break;
491515
case 'c':
492516
_it2 = _it;
493517
if(has_keyword_pattern(_it,begcode,endpycode,"consider")){
@@ -971,7 +995,8 @@ void LsysRule::set( const std::string& rule ){
971995

972996
/*---------------------------------------------------------------------------*/
973997
std::string::const_iterator next_token(std::string::const_iterator _it2,
974-
std::string::const_iterator end)
998+
std::string::const_iterator end,
999+
bool withbrackets = true)
9751000
{
9761001
if(_it2 != end){
9771002
if(*_it2 == '"'){ // skip string
@@ -997,7 +1022,7 @@ std::string::const_iterator next_token(std::string::const_iterator _it2,
9971022
}
9981023
if(_it2 != end)_it2++;
9991024
}
1000-
else if(*_it2 == '['){ // skip array
1025+
else if(withbrackets && *_it2 == '['){ // skip array
10011026
int nbOpenBracket = 1;
10021027
while(_it2 != end && (*_it2 != ']' || nbOpenBracket > 0)){
10031028
_it2++;
@@ -1010,7 +1035,7 @@ std::string::const_iterator next_token(std::string::const_iterator _it2,
10101035
}
10111036
if(_it2 != end)_it2++;
10121037
}
1013-
else if(*_it2 == '{'){ // skip dict
1038+
else if(withbrackets && *_it2 == '{'){ // skip dict
10141039
int nbOpenBracket = 1;
10151040
while(_it2 != end && (*_it2 != '}' || nbOpenBracket > 0)){
10161041
_it2++;
@@ -1043,20 +1068,23 @@ LsysRule::parseHeader( const std::string& header){
10431068
bool begncd = false;
10441069
while(it != end){
10451070
if(*it == '<'){
1071+
10461072
if(!pred.empty())LsysError("Ill-formed Rule Header : "+header,"",lineno);
10471073
if(*(it+1) == '<'){
10481074
if(ncg.empty())ncg = std::string(beg,it);
10491075
else LsysError("Ill-formed Rule Header : "+header,"",lineno);
10501076
it++;
10511077
}
10521078
else {
1053-
if(cg.empty())cg = std::string(beg,it);
1079+
if(cg.empty()) cg = std::string(beg,it);
10541080
else LsysError("Ill-formed Rule Header : "+header,"",lineno);
10551081
}
10561082
beg = it+1;
10571083
}
1058-
else if(*it == '>'){
1059-
if(*(it+1) == '>') {
1084+
1085+
else if(*it == '>'){
1086+
1087+
if(*(it+1) == '>') {
10601088
if (begncd || !ncd.empty())LsysError("Ill-formed Rule Header : Two new left contexts found : "+header,"",lineno);
10611089
else {
10621090
if(pred.empty()) pred = std::string(beg,it);
@@ -1075,7 +1103,7 @@ LsysRule::parseHeader( const std::string& header){
10751103
if(pred.empty())LsysError("Ill-formed Rule Header : No Predecessor found : "+header,"",lineno);
10761104
beg = it+1;
10771105
}
1078-
it = next_token(it,end);
1106+
it = next_token(it,end,false);
10791107
// it++;
10801108
}
10811109
if(pred.empty()){
@@ -1141,34 +1169,34 @@ std::string LpyParsing::lstring2pyparam( std::string::const_iterator& beg,
11411169
std::string result;
11421170
std::string::const_iterator initbeg = beg;
11431171
std::vector<std::pair<size_t,std::string> > parsedstring = parselstring(beg, endpos, delim, lineno,true);
1144-
ParametricProduction pprod;
1172+
ParametricProductionPtr pprod = ParametricProduction::create();
11451173
if(parsedstring.empty()){
1146-
pprod.append_module_type("None");
1174+
pprod->append_module_type("None");
11471175
}
11481176
else {
11491177
for(std::vector<std::pair<size_t,std::string> >::const_iterator it = parsedstring.begin();
11501178
it != parsedstring.end(); ++it){
11511179
if (it->first == ModuleClass::GetModule->getId()){
11521180
// in the case of production $ is only followed by a var name.
1153-
pprod.append_variable_module();
1181+
pprod->append_variable_module();
11541182
result += "," + it->second;
11551183
}
11561184
else {
1157-
pprod.append_module_type(it->first);
1185+
pprod->append_module_type(it->first);
11581186
if (!it->second.empty()) {
11591187
std::vector<std::string> args = parse_arguments(it->second);
11601188
for(std::vector<std::string>::const_iterator itArg = args.begin(); itArg != args.end(); ++itArg){
11611189
if(isAConstant(*itArg)){
1162-
pprod.append_module_value(LsysContext::current()->evaluate(*itArg));
1190+
pprod->append_module_value(LsysContext::current()->evaluate(*itArg));
11631191
}
11641192
else {
11651193
std::string m = "PackedArgs(";
11661194
if(itArg->size() > m.size() && std::string(itArg->begin(),itArg->begin()+m.size()) == m) {
1167-
pprod.append_module_star_variable();
1195+
pprod->append_module_star_variable();
11681196
result += "," + std::string(itArg->begin()+m.size(),itArg->end()-1);
11691197
}
11701198
else {
1171-
pprod.append_module_variable();
1199+
pprod->append_module_variable();
11721200
result += "," + *itArg;
11731201
}
11741202
}
@@ -1177,7 +1205,8 @@ std::string LpyParsing::lstring2pyparam( std::string::const_iterator& beg,
11771205
}
11781206
} // end for
11791207
}
1180-
size_t id = LsysContext::current()->add_pproduction(pprod);
1208+
LsysContext::current()->add_pproduction(pprod);
1209+
size_t id = pprod->pid();
11811210
if(pprod_id) *pprod_id = id;
11821211
size_t nbInitialLine = std::count(initbeg,beg,'\n');
11831212
size_t nbResultLine = std::count(result.begin(),result.end(),'\n');

src/cpp/lsyscontext.cpp

+62-11
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,27 @@ LsysContext::operator=(const LsysContext& lsys)
284284
return *this;
285285
}
286286

287+
void
288+
LsysContext::importContext(const LsysContext& other)
289+
{
290+
// declareModules(other.declaredModules());
291+
size_t nb = __modules.size();
292+
293+
__modules.insert(__modules.end(),other.__modules.begin(),other.__modules.end());
294+
__modulesvtables.insert(__modulesvtables.end(),other.__modulesvtables.begin(),other.__modulesvtables.end());
295+
296+
bool iscurrent = isCurrent();
297+
for(ModuleClassList::iterator it = __modules.begin()+nb; it != __modules.end(); ++it)
298+
{
299+
(*it)->activate(iscurrent);
300+
}
301+
302+
add_pproductions(other.get_pproductions());
303+
updateFromContextNamespace(other);
304+
305+
}
306+
307+
287308
LsysContext::~LsysContext()
288309
{
289310
DecTracker(LsysContext)
@@ -412,17 +433,27 @@ LsysContext::ignore(const std::string& modules){
412433
bool
413434
LsysContext::isConsidered(const std::string& module) const{
414435
if(__keyword.empty())return true;
415-
ModuleClassSet::const_iterator _it = __keyword.find(ModuleClassTable::get().getClass(module)->getId());
436+
ModuleClassPtr mclass = ModuleClassTable::get().getClass(module);
437+
ModuleClassSet::const_iterator _it = __keyword.find(mclass->getId());
416438
if(__ignore_method) return _it == __keyword.end();
417-
else return _it != __keyword.end();
439+
else {
440+
if (_it != __keyword.end()) return true;
441+
else return mclass->isBracket(); // by default we consider always bracket
442+
// return _it != __keyword.end();
443+
}
418444
}
419445

420446
bool
421447
LsysContext::isIgnored(const std::string& module) const{
422448
if(__keyword.empty())return false;
423-
ModuleClassSet::const_iterator _it = __keyword.find(ModuleClassTable::get().getClass(module)->getId());
424-
if(__ignore_method) return _it != __keyword.end();
425-
else return _it == __keyword.end();
449+
ModuleClassPtr mclass = ModuleClassTable::get().getClass(module);
450+
ModuleClassSet::const_iterator _it = __keyword.find(mclass->getId());
451+
if(__ignore_method) return _it != __keyword.end();
452+
else {
453+
if (_it != __keyword.end()) return false;
454+
else return !mclass->isBracket(); // by default we consider always bracket
455+
// return _it == __keyword.end();
456+
}
426457
}
427458

428459
bool
@@ -478,6 +509,15 @@ LsysContext::declare(const std::string& modules)
478509
}
479510
}
480511

512+
void LsysContext::declareModules(const ModuleClassList& other) {
513+
size_t nb = __modules.size();
514+
__modules.insert(__modules.end(),other.begin(),other.end());
515+
bool iscurrent = isCurrent();
516+
for(ModuleClassList::iterator it = __modules.begin()+nb; it != __modules.end(); ++it)
517+
{
518+
(*it)->activate(iscurrent);
519+
}
520+
}
481521

482522
void
483523
LsysContext::undeclare(const std::string& modules)
@@ -571,14 +611,24 @@ LsysContext::copyObject(const std::string& name, LsysContext * sourceContext)
571611
}
572612

573613

614+
574615
void
575616
LsysContext::updateNamespace(const boost::python::dict& d){
617+
PyDict_Update(Namespace(),d.ptr());
618+
}
619+
620+
void
621+
LsysContext::updateFromContextNamespace(const LsysContext& other)
622+
{
623+
PyDict_Update(Namespace(),other.Namespace());
576624
}
577625

578626
void
579627
LsysContext::getNamespace(boost::python::dict& d) const{
628+
PyDict_Update(d.ptr(),Namespace());
580629
}
581630

631+
582632
void
583633
LsysContext::clearNamespace() {
584634
}
@@ -1034,6 +1084,12 @@ GlobalContext::getObject(const std::string& name, const boost::python::object& d
10341084
}
10351085
}
10361086

1087+
void
1088+
GlobalContext::clearNamespace() {
1089+
// PyDict_Clear(__namespace.get());
1090+
__local_namespace.clear();
1091+
}
1092+
10371093
void
10381094
GlobalContext::setObject(const std::string& name,
10391095
const boost::python::object& o){
@@ -1045,11 +1101,6 @@ GlobalContext::delObject(const std::string& name) {
10451101
PyDict_DelItemString(__namespace.get(),name.c_str());
10461102
}
10471103

1048-
void
1049-
GlobalContext::clearNamespace() {
1050-
// PyDict_Clear(__namespace.get());
1051-
__local_namespace.clear();
1052-
}
10531104

10541105
void
10551106
GlobalContext::updateNamespace(const dict& d){
@@ -1058,7 +1109,7 @@ GlobalContext::updateNamespace(const dict& d){
10581109

10591110
void
10601111
GlobalContext::getNamespace(dict& d) const{
1061-
PyDict_Merge(d.ptr(),__namespace.get(),true);
1112+
PyDict_Update(d.ptr(),__namespace.get());
10621113
}
10631114

10641115

src/cpp/lsyscontext.h

+14-10
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class LPY_API LsysContext {
6161
/** Destructor */
6262
virtual ~LsysContext();
6363

64-
/** clear context. Set python namespace to default. Keep __builtin__, pylsystems and __filename__ object */
64+
/** clear context. Set python namespace to default. Keep __builtin__, lpy and __filename__ object */
6565
void clear();
6666
/** Test whether namespace is empty */
6767
bool empty() const;
@@ -138,6 +138,7 @@ class LPY_API LsysContext {
138138
virtual void clearNamespace();
139139
virtual void updateNamespace(const boost::python::dict&);
140140
virtual void getNamespace(boost::python::dict&) const;
141+
virtual void updateFromContextNamespace(const LsysContext&);
141142

142143
/** access to python object of the namespace */
143144
virtual bool hasObject(const std::string& name) const;
@@ -186,23 +187,23 @@ class LPY_API LsysContext {
186187
inline void set_nproduction(const AxialTree& prod) { __nproduction = prod; }
187188

188189
/** parametric production */
189-
inline size_t add_pproduction(const ParametricProduction& pprod)
190-
{ size_t id = __paramproductions.size(); __paramproductions.push_back(pprod); return id; }
190+
inline void add_pproduction(const ParametricProductionPtr pprod)
191+
{ __paramproductions.push_back(pprod); }
191192

192-
inline const ParametricProduction& get_pproduction(size_t id) const
193-
{ lpyassert(id <__paramproductions.size()); return __paramproductions[id]; }
193+
inline void add_pproductions(const ParametricProductionList& pprod)
194+
{ __paramproductions.insert(__paramproductions.end(),pprod.begin(),pprod.end()); }
194195

195196
inline const ParametricProductionList& get_pproductions() const
196197
{ return __paramproductions; }
198+
197199

198200
inline AxialTree generate(size_t pprod_id, const bp::list& args)
199-
{ lpyassert(pprod_id<__paramproductions.size()); return __paramproductions[pprod_id].generate(args); }
201+
{ return ParametricProduction::get(pprod_id)->generate(args); }
200202

201203

202204
inline AxialTree generate(const bp::tuple& args)
203-
{ size_t pprod_id = bp::extract<size_t>(args[0])();
204-
lpyassert(pprod_id<__paramproductions.size());
205-
return __paramproductions[pprod_id].generate(args); }
205+
{ size_t pprod_id = bp::extract<size_t>(args[0])();
206+
return ParametricProduction::get(pprod_id)->generate(args); }
206207

207208
inline void pproduce(size_t pprod_id, const bp::list& args)
208209
{ __nproduction.append(generate(pprod_id,args)); }
@@ -255,6 +256,8 @@ class LPY_API LsysContext {
255256
bool isDeclared(const std::string& module);
256257
bool isDeclared(ModuleClassPtr module);
257258
ModuleClassList declaredModules() const { return __modules; }
259+
void declareModules(const ModuleClassList& other);
260+
258261
void declareAlias(const std::string& aliasName, ModuleClassPtr module);
259262

260263
void setModuleScale(const std::string& modules, int scale);
@@ -274,7 +277,8 @@ class LPY_API LsysContext {
274277
bool isEarlyReturnEnabled() ;
275278
inline void stop() { enableEarlyReturn(true); }
276279

277-
280+
void importContext(const LsysContext& other);
281+
278282
/** Iteration number property. Only set by Lsystem. Access by all other. */
279283
public:
280284
size_t getIterationNb();

0 commit comments

Comments
 (0)