静态文本分析, spirit 和其他(一)

最近工作中要用到一些静态文本分析的功能, 大体说来就是按照内部定义的格式解析一个配置文件.以前也做过类似的工作, 当时想当然直接用win32 API读取INI文件.当然项目是完成了,而时隔几年之后, 又要用到类似的功能, 有什么其他解决方案呢.

这里不得不提到DSLEBNF.具体的定义实在不是三言两语能讲得清楚的, 不过好在我们有wiki.

基本上, 我们定义自己的配置文件格式, 相当于定义了自己的文法.而在应用中, 按照我们事先定义好的文法来解析并读取这些配置文件, 也就完成了这一循环.

忘记在哪里看到这么一句话"C++程序员都是脑力劳动的施虐者和受虐者", 所以我们有了Boost. 而我们的boost::spirit, 帮我们提供了一个绝好的定义DSL的工具.

从这篇文章开始, 我会用一个个的小例子来逐渐引入spirit, 最后实现并超过原有的需求.

很多例子以及源代码都是来在网络, 包括但不限于(http://boost-spirit.com/home/, http://www.codeproject.com/, 等等)

<一> 计算器

这是Spirit的作者推荐的快速开始的例子,废话少说, 主要的代码如下(稍微做了些修改)

struct CalculatorParser : public grammar<CalculatorParser>
{
    template<typename ScannerType>
    struct definition
    {
	definition(const CalculatorParser & c) 
	{

	    factor = real_p[& push_real] 
	        | '(' >> expression >> ')' 
		| ('-' >> factor[&do_neg]) 
		| ('+' >> factor);


	    term = factor >> 
		*(
		  ('*' >> factor[Calculator<multiplies<double> >()])
		| ('/' >> factor[Calculator<divides<double> >()])
		);

	    expression = term >> 
		*(
		  ('+' >> term[Calculator<plus<double> >()])
		| ('-' >> term[Calculator<minus<double> >()])
		) >> 
		ch_p(';');
	}

	rule<ScannerType> expression, term, factor;

	rule<ScannerType> const& 
	    start() const 
	{ 
	    return expression; 
	}
    };

};

 

文法的核心就定义在expression, term, factor中了

factor是基本单元, 在满足real_p的时候(即factor是个real variable), 执行push_real(函数指针)

而factor也可以是括号内的表达式, 负数或显式指定的正数

term在做乘除运算而expression则是在做加减运算,同时整个表达式以";"作为结束符

以上我们就定义了一个非常简单的EBNF,如何,方便吧

 

使用时,直接parse即可

parse_info<> info = parse("1+2;", CalculatorParser());

 

以上, 我们简单接触了EBNF, 可以看出了,要想解析自定义的格式, 使用spirit是非常方便的一件事

下一篇, 我们会来看一个稍微复杂些的例子, 并用到更多的功能

原文链接: https://www.cnblogs.com/rc-tech/archive/2010/05/26/1744710.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    静态文本分析, spirit 和其他(一)

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/11205

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月7日 上午12:55
下一篇 2023年2月7日 上午12:56

相关推荐