rustlr 0.3.0

LR/LALR parser generator that can automatically create abstract syntax trees
Documentation


                // <COMMA*>
                let newtok; // will be new strtok
		let retoks:Vec<&str> = strtok.split(':').collect();
		if retoks.len()>0 && retoks[0].len()>1 && (retoks[0].ends_with('*') || retoks[0].ends_with('+') || retoks[0].ends_with('?')) {
		   strtok = retoks[0]; // to be changed back to normal a:b
		   let defaultrelab = format!("_item{}_",i-1-iadjust);
		   let relabel = if retoks.len()>1 && retoks[1].len()>0 {retoks[1]} else {&defaultrelab};
		   let mut gsympart = strtok[0..strtok.len()-1].trim(); //no *
                   if gsympart=="_" {gsympart="_WILDCARD_TOKEN_";}
		   let errmsg = format!("unrecognized grammar symbol '{}', line {}",gsympart,linenum);
		   let gsymi = *self.Symhash.get(gsympart).expect(&errmsg);
		   let newntname = format!("NEWNT{}_{}_{}",gsympart,self.Rules.len(),ntcnt); ntcnt+=1;
		   let mut newnt = Gsym::new(&newntname,false);
                   newnt.rusttype = "()".to_owned();
                   // following means symbols such as -? will not be
                   // part of ast type unless there is a given label: -?:m
                   if &self.Symbols[gsymi].rusttype!="()" || (retoks.len()>1 && retoks[1].len()>0) {
		     newnt.rusttype = if strtok.ends_with('?') {
                       if self.basictypes.contains(&self.Symbols[gsymi].rusttype[..]) || self.Symbols[gsymi].rusttype.starts_with("Vec") /*self.basictypes.contains(&self.Symbols[gsymi].rusttype[..])*/ {format!("Option<{}>",&self.Symbols[gsymi].rusttype)}
                       else {format!("Option<LBox<{}>>",&self.Symbols[gsymi].rusttype)}
                     }
                     else {format!("Vec<LBox<{}>>",&self.Symbols[gsymi].rusttype)};
                   }
		   if !self.enumhash.contains_key(&newnt.rusttype) {
 		     self.enumhash.insert(newnt.rusttype.clone(),ntcx);
		     ntcx+=1;
		   }
		   self.Symbols.push(newnt.clone());
		   self.Symhash.insert(newntname.clone(),self.Symbols.len()-1);
		   // add new rules
		   let mut newrule1 = Grule::new_skeleton(&newntname);
		   newrule1.lhs.rusttype = newnt.rusttype.clone();
                   newrule1.precedence = self.Symbols[gsymi].precedence;
		   if strtok.ends_with('?') {
		     newrule1.rhs.push(self.Symbols[gsymi].clone());
                     if newrule1.lhs.rusttype.starts_with("Option<LBox<") {
		       newrule1.action=String::from(" Some(parser.lbx(0,_item0_)) }"); } else if newrule1.lhs.rusttype.starts_with("Option<") {newrule1.action = String::from(" Some(_item0_) }"); } // else nothing
		   }// end with ?
		   else { // * or +
  		     newrule1.rhs.push(newnt.clone());
		     newrule1.rhs.push(self.Symbols[gsymi].clone());
                     if &newrule1.lhs.rusttype!="()" {
		       newrule1.action = String::from(" _item0_.push(parser.lbx(1,_item1_)); _item0_ }");
                     }
		   } // * or +
		   let mut newrule0 = Grule::new_skeleton(&newntname);
		   newrule0.lhs.rusttype = newnt.rusttype.clone();
		   if strtok.ends_with('+') {
		     newrule0.rhs.push(self.Symbols[gsymi].clone());
                     if &newrule0.lhs.rusttype!="()" {
		       newrule0.action=String::from(" vec![parser.lbx(0,_item0_)] }");
                     }
		   }// ends with +
		   else if strtok.ends_with('*') && &newrule0.lhs.rusttype!="()" {
		     newrule0.action = String::from(" Vec::new() }");
		   }
		   else if strtok.ends_with('?') && &newrule0.lhs.rusttype!="()" {
		     newrule0.action = String::from(" None }");
		   }
                   if self.tracelev>4 {
                     printrule(&newrule0,self.Rules.len());
                     printrule(&newrule1,self.Rules.len()+1);   
                   }                   
		   self.Rules.push(newrule0);
		   self.Rules.push(newrule1);
		   let mut rulesforset = HashSet::with_capacity(2);
		   rulesforset.insert(self.Rules.len()-2);
		   rulesforset.insert(self.Rules.len()-1);
		   newtok = format!("{}:{}",&newntname,relabel);
		   self.Rulesfor.insert(newntname,rulesforset);
		   // change strtok to new form
		   strtok = &newtok;
//println!("2 strtok now {}",strtok);                   
		}// processes RE directive - add new productions