⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bnf_ruleparser.cpp

📁 sip torture test tools
💻 CPP
字号:
//bnf_ruleparser.cpp//Copyright (C) 2003 Metalink LTD//Author: Rodionov Sergey (seger@metalinkltd.com)//This program is distributed under terms of GPL (see LICENSE)#include "bnf_ruleparser.h"#include <stdexcept>#include <cctype>#include <iostream>using namespace std;void bnf_ruleparser::create_itemlist(vector<bnf_ruleitem*>& items,				     str_cit from, str_cit end){   if (items.size()!=0)     error("Internall error in create_itemlist");   str_cit begin_from=from;   int min=1;   int max=1;   bool is_orgroup=false;   vector<bnf_ruleitem*> or_items;   //for or_items    while ( from != end)     {	if ( *from == ' ' )	  from++;	else if ( *from == '"')	  {	     items.push_back(create_str_item(from, end, min, max));	     min=max=1;	  }	else if ( *from == '%' )	  {	     items.push_back(create_hval(from, end, min, max));	     min=max=1;	  }	else if ( *from == '*' || isdigit(*from))	  read_minmax( from, end, min, max );	else if ( *from == '(' )	  {	     items.push_back(create_group(from, end, '(' , ')' ,min , max));	     min=max=1;	  }	else if ( *from == '[' )	  {	     if (min!=1 || max!=1)	       error("in create_itemlist minmax before [");	     items.push_back(create_group(from, end, '[' , ']' , 0 , 1));	  }	else if ( *from == '/' ) //Ups its or group	  {	     is_orgroup=true;	     if (min!=1 || max!=1)	       error("in create_itemlist minmax before or");	     if (items.size()==0)	       error("in create_itemlist empty or element");	     if (items.size()==1)  //can simply put	       or_items.push_back(items[0]);	     else	       or_items.push_back(new bnf_ruleitem_group(1,1,items));	     items.resize(0);	     from++;  //skip or symbol	  }	else if (isalpha(*from))	  {	     items.push_back(create_rule_item(from, end, min , max));	     min=max=1;	  }	else	  {//	     cout<<"bad char="<<(int)*from<<endl;	     error(string("in create_itemlist bad symbol=") + *from);	  }	     }      if (min!=1 || max!=1)     error("in create_itemlist minmax before end");      if (is_orgroup)     {	if (items.size() == 0 )	  error("in create_itemlist uncomplit or group");		if (items.size()==1)  //can simply put	  or_items.push_back(items[0]);	else	  or_items.push_back(new bnf_ruleitem_group(1,1,items));		items.resize(0);	items.push_back(new bnf_ruleitem_orgroup(1,1,or_items));     }}//                                                                            bnf_ruleitem* bnf_ruleparser::create_str_item(str_cit & from, str_cit end,					      int min, int max){//   cout<<"Try create str_item"<<endl;   if ( from == end || *from != '"')     error("in create_str_item Bad first symbol =");   from++;   string str;      while ( from != end && *from != '"' )     {	str.push_back(*from);	from++;     }      if ( from == end)     error("in create_str_item not found last \" symbol");      from++;  //remove " symbol      return new bnf_ruleitem_string(min, max, str);}//                                                                            bnf_ruleitem* bnf_ruleparser::create_hval(str_cit& from, str_cit end,					  int min,int max){//   cout<<"Try create hval"<<endl;   if ( from==end || *from != '%' )     error("in create_hval bad first symbol");   from++;   if (from==end || *from!='x')     error("in create_hval work only with x");   from++;   if (from==end)     error("in create_hval");   int first=read_hval(from, end);   if ( from!=end && *from == '.' )  //point by point case     {	vector<int> vval;	vval.push_back(first);	while ( from != end && *from == '.' )	  {	     from++;     //skip .	     vval.push_back(read_hval(from, end));	  }	return new bnf_ruleitem_pointhval(min,max,vval);     }   if ( from!=end && *from=='-' ) //interval variant     {	from++;	return new bnf_ruleitem_rangehval(min,max,first,read_hval(from, end));     }   return new bnf_ruleitem_rangehval(min,max,first,first);}//                                                                            bnf_ruleitem* bnf_ruleparser::create_group(str_cit& from, str_cit end,					   char open,char close,					   int min,int max){//   cout<<"Try create group"<<endl;   if ( from == end || *from != open)     error("in create_group bad first symbol");      from++;     //skip first open symbol   int num=1;   str_cit it1=from;      while ( ( from != end  ) && ( num > 0 ) )     {	if ( *from == open )	  num++;	else if (*from == close)	  num--;	from++;     }   if ( num != 0 )     error("in create_group not found last symbol");   if ((from-it1) < 2)     error("in create_group empty group");   vector<bnf_ruleitem*> items;   create_itemlist( items, it1, from - 1);   return new bnf_ruleitem_group(min, max, items);}//                                                                            bnf_ruleitem* bnf_ruleparser::create_rule_item(str_cit& from, str_cit end,					       int min,int max){//   cout<<"Try create rule item"<<endl;   if ( from==end || !isalpha(*from) )     error("in create_rule_item bad first symbol");   string str;   while ( (from != end) && (isalpha(*from) || isdigit(*from) || *from=='-' ))     {	str.push_back( *from );	from++;     }   if (rule_map->find(str) == rule_map->end())  //(str rule not found)     error(string("in create_rule_item not found rule=") + str);   return new bnf_ruleitem_rule(min, max, rule_map->operator[](str));}//                                                                            int bnf_ruleparser::read_hval(str_cit& from, str_cit end){   if ( from == end )     error("Error in read_hval");   int first = conv_hdigit(*from);   from++;   if ( from == end )     error("Error in read_hval");   int second = conv_hdigit(*from);   from++;   return first*16+second;   }//                                                                            int bnf_ruleparser::conv_hdigit(char c){   if (c>='0' && c<='9')     return c-'0';   if (c>='A' && c<='F')     return c-'A'+10;   if (c>='a' && c<='f')     return c-'a'+10;   error("Error in read_hdigit bad digit");   return 0;}//                                                                            void bnf_ruleparser::read_minmax(str_cit& from, str_cit end, int& min, int& max){   if (from==end)     error("Error in read_minmax");   min = 0;   max = bnf_ruleitem::MAX_MAX;   if (isdigit(*from))     {	min=conv_hdigit(*from);	from++;     }   if ( from == end )     error("Error in read_minmax format error");   if ( *from != '*')     {	max = min;	return;     }   from++;   //skip *   if ( from!=end && isdigit(*from))     {	max=conv_hdigit(*from);	from++;     }   if (from==end || isdigit(*from))     error("Error support only one digit in minmax (or format error)");}//                                                                            void bnf_ruleparser::error(string err){   throw logic_error(string("error in bnf_ruleparser class : ") + err);}//                                                                            bool bnf_ruleparser::read_next_rule(const char** rlist,int &n,				    string& rule_name,string& rule){   //may be before comment   if (rlist[n]==NULL)     return false;   while (rlist[n]!=NULL && !read_ruleline(rlist[n],rule_name,rule))     {	n++;	if (rlist[n]==NULL)  //not find any exept no rules	  return false;     }   remove_comments(rule);   string tmp_name,tmp;   n++;   while ( (rlist[n] != NULL) && !read_ruleline(rlist[n],tmp_name,tmp))     {	string tmp=rlist[n++];	remove_comments(tmp);	rule = rule + ' ' + tmp;     }   return true;}//                                                                            bool bnf_ruleparser::read_ruleline(const char* rline, string& rule_name,			       string& rule){   rule_name = rule = "";        //skip ' '   while (*rline==' ')     rline++;     //read rule_name   if (!isalpha(*rline))     return false;   rule_name+=*rline;   rline++;   while (isalpha(*rline) || isdigit(*rline) || *rline == '-')     {	rule_name+=*rline;	rline++;     }   while (*rline==' ')  //skip ' '     rline++;   if (*rline != '=') //Ups its not rule name     return false;   rline++;     //read rule body   while (*rline!=0)     rule+=*(rline++);   return true;}//                                                                            void bnf_ruleparser::remove_comments(string & s){   bool in_dq=false;   for (unsigned int i=0;i<s.size();i++)     {	if (s[i]=='"')	  in_dq = !in_dq;	if (s[i]==';' && (!in_dq))	  {	     string tmp(s,0,i);	     s=tmp;	     return;	  }     }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -