自从几天前被 spirit 的精妙所折服后,就萌生了要用它写一个MDX解析器的想法。
由于完整的MDX相当复杂,一次性到位有相当难度。要做大事,先从小事做起,所以就先取MDX的一个小片断来先做尝试。MDX中最常用的莫过于SELECT语句,就单单SELECT语句还是很复杂,于是就做了大大的简略,将with字句,where字句,以及其他许多可选项省去,总之简略的不能再简略了。基本能解析如下的MDX片断:
select
{[Measures].[Amount],[Measures].[Internet Order Count]}
on columns,
{[Date].[Calendar].[Calendar Year].&[2001],
[Date].[Calendar].[Calendar Year].&[2002],
[Date].[Calendar].[Calendar Year].&[2003],
[Date].[Calendar].[Calendar Year].&[2004]
} on rows
from
[Adventure Works]

旨在学习spirit的使用。

Download full source code

以下就是使用 spirit 构造的解析器.spirit 在 character level  工作,所以不需要一个词法分析的阶段,str_p("select") ,str_p("from") 这样的rule就可以解析 select,from 关键词了,十分便捷!

 1 struct mdx_select : public grammar<mdx_select>
 2 {
 3     template <typename ScannerT>
 4     struct definition
 5     {
 6         definition(mdx_select const& /*self*/)
 7         {
 8             
 9             select_statement 
10                 =    as_lower_d[str_p("select")]
11                     >> axis_specification_list
12                     >> as_lower_d[str_p("from")]
13                     >> cube_name[&do_cube];
14 
15             axis_specification_list 
16                 =    axis_specification 
17                     >>  *(ch_p(','>> axis_specification);
18 
19             // <axis_specification> ::= <set> ON <axis_name>
20             axis_specification 
21                 =    set_expression >> as_lower_d[str_p("on")] >> axis_name;
22 
23             set_expression 
24                 =  ch_p('{'
25                     >> member_list 
26                     >> ch_p('}');
27 
28             member_list
29                 = member_expression [&do_members] 
30                     >> *(ch_p(",">> member_expression[&do_members]  );
31 
32             member_expression
33                 = lexeme_d[+(alnum_p|ch_p('_')|ch_p('&')|ch_p('.')|ch_p('[')|ch_p(']')|ch_p('\x20'))];
34 
35             axis_name
36                 =    as_lower_d[str_p("columns")][do_copy_members(col_members)] 
37                     | as_lower_d[str_p("rows")][do_copy_members(row_members)]
38                     | as_lower_d[str_p("axis0")][do_copy_members(col_members)] 
39                     | as_lower_d[str_p("axis1")][do_copy_members(row_members)];
40 
41             cube_name
42                 = lexeme_d[+print_p];
43             
44         }
45 
46         rule<ScannerT> select_statement,axis_specification_list,axis_specification,
47             set_expression,member_list,member_expression,axis_name,cube_name;
48         rule<ScannerT> const&
49 
50         start() const { return select_statement; }
51     };
52 };

spirit 的简单介绍和下载安装使用,请参见
http://www.cnblogs.com/nemowang/archive/2007/05/11/743155.html

Posted on 2007-05-14 01:08  Nemo Wang  阅读(953)  评论(1编辑  收藏  举报
若不是耶和华建造房屋,建造的人就枉然劳力; 若不是耶和华看守城池,看守的人就枉然警醒。