LL(1)语法分析之first、follow的实现
来源:互联网 发布:录制脚本的软件 编辑:程序博客网 时间:2024/06/06 00:12
#include <cassert>
#include <functional>
#include <iostream>
#include <map>
#include <tr1/memory>
#include <set>
#include <vector>
class non_copy_constructor {
public:
non_copy_constructor();
private:
non_copy_constructor(const non_copy_constructor &);
};
class has_virtual_destructor {
public:
virtual ~has_virtual_destructor();
};
class grammar_symbol:public non_copy_constructor, public has_virtual_destructor {
class _compare_type;
protected:
grammar_symbol();
public:
typedef std::tr1::shared_ptr<const grammar_symbol> handle_type;
typedef std::set<handle_type, _compare_type> set_type;
virtual const set_type first() const=0;
virtual const set_type follow() const=0;
};
class symbol_factor;
class end_symbol:public grammar_symbol {
friend class symbol_factor;
public:
const set_type first() const;
const set_type follow() const;
};
class empty_symbol:public grammar_symbol {
friend class symbol_factor;
public:
const set_type first() const;
const set_type follow() const;
};
class named_symbol:public grammar_symbol {
protected:
named_symbol(char);
public:
char name() const;
private:
const char _name_m;
};
class termination_symbol:public named_symbol {
friend class symbol_factor;
protected:
termination_symbol(char);
public:
const set_type first() const;
const set_type follow() const;
};
class nonterminal_symbol:public named_symbol {
friend class symbol_factor;
protected:
nonterminal_symbol(char, const std::vector<std::vector<handle_type> > &);
public:
const set_type first() const;
const set_type follow() const;
private:
void _production_first(set_type &, const std::vector<handle_type> &) const;
void _import_nonempty_symbol(set_type &, handle_type) const;
void _import_other_symbol(set_type &, const std::vector<handle_type> &) const;
bool _have_empty_symbol(handle_type) const;
void _productions_follow(set_type &, const nonterminal_symbol *) const;
void _production_follow(set_type &, const nonterminal_symbol *, const std::vector<handle_type> &) const;
void _include_this_follow(set_type &, const nonterminal_symbol *) const;
const std::vector<std::vector<handle_type> > _productions_m;
};
class symbol_factor {
friend class nonterminal_symbol;
static grammar_symbol::handle_type get_end_symbol();
public:
typedef std::map<int, grammar_symbol::handle_type> map_type;
static grammar_symbol::handle_type get_empty_symbol();
static grammar_symbol::handle_type get_termination_symbol(char);
static grammar_symbol::handle_type get_nonterminal_symbol(char);
static void set_nonterminal_symbol(char, const std::vector<std::vector<grammar_symbol::handle_type> > &);
static void set_start_symbol(char);
private:
static map_type _symbols_s;
static char _start_s;
};
class grammar_symbol::_compare_type:public std::binary_function<grammar_symbol::handle_type, grammar_symbol::handle_type, bool> {
public:
result_type operator()(first_argument_type, second_argument_type);
};
non_copy_constructor::non_copy_constructor() {}
has_virtual_destructor::~has_virtual_destructor() {}
grammar_symbol::grammar_symbol() {}
const grammar_symbol::set_type end_symbol::first() const {assert(false);}
const grammar_symbol::set_type end_symbol::follow() const {assert(false);}
const grammar_symbol::set_type empty_symbol::first() const {
set_type _result;
_result.insert(symbol_factor::get_empty_symbol());
return _result;
}
const grammar_symbol::set_type empty_symbol::follow() const {assert(false);}
named_symbol::named_symbol(char _name):_name_m(_name) {}
char named_symbol::name() const {return _name_m;}
termination_symbol::termination_symbol(char _name):named_symbol(_name) {}
const grammar_symbol::set_type termination_symbol::first() const {
set_type _result;
_result.insert(symbol_factor::get_termination_symbol(name()));
return _result;
}
const grammar_symbol::set_type termination_symbol::follow() const {assert(false);}
nonterminal_symbol::nonterminal_symbol(char _name, const std::vector<std::vector<handle_type> > &_productions):named_symbol(_name), _productions_m(_productions) {}
const grammar_symbol::set_type nonterminal_symbol::first() const {
set_type _result;
for(std::vector<std::vector<handle_type> >::const_iterator _i=_productions_m.begin(); _i!=_productions_m.end(); ++_i)
_production_first(_result, *_i);
return _result;
}
const grammar_symbol::set_type nonterminal_symbol::follow() const {
set_type _result;
if(name()==symbol_factor::_start_s)
_result.insert(symbol_factor::get_end_symbol());
for(symbol_factor::map_type::const_iterator _i=symbol_factor::_symbols_s.begin(); _i!=symbol_factor::_symbols_s.end(); ++_i) {
const nonterminal_symbol *_p=dynamic_cast<const nonterminal_symbol *>(_i->second.get());
if(_p&&_p->name()!=name()) _productions_follow(_result, _p);
}
return _result;
}
void nonterminal_symbol::_production_first(set_type &_result, const std::vector<handle_type> &_curr) const {
_import_nonempty_symbol(_result, _curr.front());
_import_other_symbol(_result, _curr);
}
void nonterminal_symbol::_import_nonempty_symbol(set_type &_result, handle_type _curr) const {
const set_type _curr_first=_curr->first();
for(set_type::const_iterator _i=_curr_first.begin(); _i!=_curr_first.end(); ++_i)
if(!dynamic_cast<const empty_symbol *>(_i->get()))
_result.insert(*_i);
}
void nonterminal_symbol::_import_other_symbol(set_type &_result, const std::vector<handle_type> &_curr) const {
for(std::vector<handle_type>::const_iterator _i=_curr.begin(); _i!=_curr.end(); ++_i) {
if(!_have_empty_symbol(*_i)) return;
if(_i+1!=_curr.end())
_import_nonempty_symbol(_result, *(_i+1));
}
_result.insert(symbol_factor::get_empty_symbol());
}
bool nonterminal_symbol::_have_empty_symbol(handle_type _curr) const {
const set_type &_curr_first=_curr->first();
for(set_type::const_iterator _i=_curr_first.begin(); _i!=_curr_first.end(); ++_i)
if(dynamic_cast<const empty_symbol *>(_i->get()))
return true;
return false;
}
void nonterminal_symbol::_productions_follow(set_type &_result, const nonterminal_symbol *_ptr) const {
for(std::vector<std::vector<handle_type> >::const_iterator _i=_ptr->_productions_m.begin(); _i!=_ptr->_productions_m.end(); ++_i)
_production_follow(_result, _ptr, *_i);
}
void nonterminal_symbol::_production_follow(set_type &_result, const nonterminal_symbol *_ptr, const std::vector<handle_type> &_production) const {
for(std::vector<handle_type>::const_iterator _i=_production.begin(); _i!=_production.end(); ++_i) {
const nonterminal_symbol *_p=dynamic_cast<const nonterminal_symbol *>(_i->get());
if(_p&&_p->name()==name()) {
if(_i+1!=_production.end())
_import_nonempty_symbol(_result, *(_i+1));
if(_i+1==_production.end()||_have_empty_symbol(*(_i+1)))
_include_this_follow(_result, _ptr);
}
}
}
void nonterminal_symbol::_include_this_follow(set_type &_result, const nonterminal_symbol *_ptr) const {
const set_type _curr_follow=_ptr->follow();
_result.insert(_curr_follow.begin(), _curr_follow.end());
}
grammar_symbol::_compare_type::result_type grammar_symbol::_compare_type::operator()(first_argument_type _x, second_argument_type _y) {
if(!dynamic_cast<const empty_symbol *>(_x.get())) return true;
if(!dynamic_cast<const empty_symbol *>(_y.get())) return false;
return dynamic_cast<const named_symbol *>(_x.get())->name()<dynamic_cast<const named_symbol *>(_y.get())->name();
}
grammar_symbol::handle_type symbol_factor::get_end_symbol() {
return _symbols_s[-1].get()?_symbols_s[-1]:_symbols_s[-1]=grammar_symbol::handle_type(new end_symbol);
}
grammar_symbol::handle_type symbol_factor::get_empty_symbol() {
return _symbols_s[0].get()?_symbols_s[0]:_symbols_s[0]=grammar_symbol::handle_type(new empty_symbol);
}
grammar_symbol::handle_type symbol_factor::get_termination_symbol(char _name) {
assert(islower(_name));
return _symbols_s[_name].get()?_symbols_s[_name]:_symbols_s[_name]=grammar_symbol::handle_type(new termination_symbol(_name));
}
grammar_symbol::handle_type symbol_factor::get_nonterminal_symbol(char _name) {
assert(isupper(_name)&&_symbols_s[_name].get());
return _symbols_s[_name];
}
void symbol_factor::set_nonterminal_symbol(char _name, const std::vector<std::vector<grammar_symbol::handle_type> > &_productions) {
assert(isupper(_name)&&!_symbols_s[_name].get()&&!_productions.empty()&&!_productions.front().empty());
_symbols_s[_name]=grammar_symbol::handle_type(new nonterminal_symbol(_name, _productions));
}
void symbol_factor::set_start_symbol(char _name) {
assert(isupper(_name)&&_symbols_s[_name]);
_start_s=_name;
}
symbol_factor::map_type symbol_factor::_symbols_s;
char symbol_factor::_start_s;
int main(int argc, char *argv[]) {
std::vector<std::vector<grammar_symbol::handle_type> > _psB;
std::vector<grammar_symbol::handle_type> _pB;
_pB.push_back(symbol_factor::get_termination_symbol('b'));
_psB.push_back(_pB);
symbol_factor::set_nonterminal_symbol('B', _psB);
std::vector<std::vector<grammar_symbol::handle_type> > _psA;
std::vector<grammar_symbol::handle_type> _pA;
_pA.push_back(symbol_factor::get_nonterminal_symbol('B'));
_pA.push_back(symbol_factor::get_termination_symbol('a'));
_psA.push_back(_pA);
symbol_factor::set_nonterminal_symbol('A', _psA);
symbol_factor::set_start_symbol('A');
const grammar_symbol::set_type _follow=symbol_factor::get_nonterminal_symbol('B')->follow();
std::cout<<"{";
for(grammar_symbol::set_type::const_iterator _i=_follow.begin(); _i!=_follow.end(); ++_i) {
if(dynamic_cast<const end_symbol *>(_i->get())) {
if(_i!=_follow.begin())
std::cout<<", [end]";
else
std::cout<<"[end]";
}
else if(dynamic_cast<const empty_symbol *>(_i->get())) {
if(_i!=_follow.begin())
std::cout<<", [empty]";
else
std::cout<<"[empty]";
}
else {
if(_i!=_follow.begin())
std::cout<<", "<<dynamic_cast<const termination_symbol *>(_i->get())->name();
else
std::cout<<dynamic_cast<const termination_symbol *>(_i->get())->name();
}
}
std::cout<<"}"<<std::endl;
return 0;
}
- LL(1)语法分析之first、follow的实现
- LL(1)文法判别之First集合、Follow集合、Select集合求法
- c++实现LL(1)赋值语句的语法分析
- 编译原理中LL(1)文法求FIRST集和FOLLOW集的方法
- 编译原理:first集合和follow集合的求法及LL(1)文法判定
- first集,follow集,LL(1)分析表
- follow集 first集 LL(1)文法判别
- 【C++】C++实现LL(1)语法分析
- 语法分析之LL(1)分析法
- LL(1)语法分析
- LL(1)语法分析
- LL(1)语法分析
- LL(1)语法分析程序
- 语法分析--左递归的消除,FIRST集合FOLLOW集的求解
- 用JAVA实现LL(1)文法语法分析程序
- Notes-4:C++练习之LL(1)语法分析
- 编译原理FIRST集、FOLLOW集、SELECT集求法通俗解释 & LL(1)文法判定
- 自上而下语法分析LL(1)
- 大型项目使用Automake/Autoconf完成编译配置(2)——步步为营
- 包的细化程度有时与系统的稳定程度呈反比
- 确定的有穷自动机正则表达式求值
- poj2000
- 不确定有穷自动机正则表达式求值
- LL(1)语法分析之first、follow的实现
- 博弈好题 poi2004 gra
- jdk jre jvm 与 java环境变量
- redhat enterprise 5 简单配置yum 源
- 设置classpath环境变量详解
- 聚类算法(2)
- no search paths found in this AVD's configuration
- 嵌入式操作系统uCLinux
- jdbc连接数据库步骤