📄 bnf_ruleparser.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 + -