使用 spirit 解析 MDX

 自从几天前被 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

你可能感兴趣的:(SPI)