随笔-91  评论-137  文章-0  trackbacks-0
本文的思路来源于http://www.cppblog.com/vczh/archive/2008/05/21/50656.html

首先先看代码:
  1 #include <stdio.h>
  2 
  3 class Element
  4 {
  5 public:
  6     Element() : start(0),length(0){}
  7 
  8     int start;
  9     int* data;
 10     int length;
 11 };
 12 
 13 template<class T>
 14 class Fail
 15 {
 16 public:
 17     int Parser(T& s)
 18     {
 19         return 0;
 20     }
 21     
 22     bool same(T s1,T s2)
 23     {
 24         for(int i=s1.start;i<s2.length;i++)
 25             if(s1.data[i] != s2.data[i])
 26                 return false;
 27         return true;
 28     }
 29 };
 30 
 31 template<class T>
 32 class Ch : public Fail<T>
 33 {
 34 public:
 35     int Parser(T& s1,T s2)
 36     {
 37         Fail<T> t;
 38         if(s1.length >= s2.length)
 39             if(same(s1,s2))
 40             {
 41                 s1.start += s2.length;
 42                 return s2.length;
 43             }
 44         return t.Parser(s1);
 45     }
 46 };
 47 
 48 template<class T>
 49 class Seq : public Fail<T>
 50 {
 51 public:
 52     int Parser(T& s1,T s2,T s3)
 53     {
 54         Fail<T> t;
 55         Ch<T> ch1,ch2;
 56         int n1 = ch1.Parser(s1,s2);
 57         int n2 = ch2.Parser(s1,s3);
 58         if(n1 && n2) return n1 + n2;
 59         else return t.Parser(s1);
 60     }
 61 };
 62 
 63 template<class T>
 64 class Alt : public Fail<T>
 65 {
 66 public:
 67     int Parser(T& s1,T s2,T s3)
 68     {
 69         Fail<T> t;
 70         Ch<T> ch1,ch2;
 71         int n1 = ch1.Parser(s1,s2);
 72         int n2 = ch2.Parser(s1,s2);
 73         if(n1) return n1;
 74         else if(n2) return n2;
 75         else return t.Parser(s1);
 76     }
 77 };
 78 
 79 template<class T,int max>
 80 class Any : public Fail<T>
 81 {
 82 public:
 83     int Parser(T& s1,T s2)
 84     {
 85         Fail<T> t;
 86         for(int i=0;i<max;i++)
 87             if(!same(s1,s2))
 88                 return t.Parser(s1);
 89         return s2.length * max;
 90     }
 91 };
 92 
 93 void main()
 94 {
 95     Element s1;
 96     Element s2,s3;
 97     s1.data = new int[6];
 98     s1.length = 6;
 99     s1.data[0= 0;
100     s1.data[1= 1;
101     s1.data[2= 2;
102     s1.data[3= 3;
103     s1.data[4= 4;
104     s1.data[5= 5;
105     s2.data = new int[1];
106     s2.length = 1;
107     s2.data[0= 0;
108     s3.data = new int[1];
109     s3.length = 1;
110     s3.data[0= 1;
111     
112     // Seq Test
113     Seq<Element> seq;
114     int n = seq.Parser(s1,s2,s3);
115     printf("Seq is:%d\n",n);
116     
117     // Alt Test
118     s1.start = 0;
119     Alt<Element> alt;
120     n = alt.Parser(s1,s2,s3);
121     printf("Alt is:%d\n",n);
122     
123     // Any Test
124     s1.start = 0;
125     s1.data[1= 0;
126     Any<Element,2> any;
127     n = any.Parser(s1,s2);
128     printf("Any is:%d\n",n);
129     
130     delete[] s1.data;
131     delete[] s2.data;
132     delete[] s3.data;
133 }

Element可理解为字符串结构,其中的start成员变量表示输入串当前分析到的指针.

我们首先需要一个Fail,这个对象表示分析失败,无论输入是什么都返回0.
 1 template<class T>
 2 class Fail
 3 {
 4 public:
 5     int Parser(T& s)
 6     {
 7         return 0;
 8     }
 9     
10     bool same(T s1,T s2)
11     {
12         for(int i=s1.start;i<s2.length;i++)
13             if(s1.data[i] != s2.data[i])
14                 return false;
15         return true;
16     }
17 };
same函数用于分析输入串s1与待验证串s2是否完全匹配.

然后我们需要一个Ch,这个对象分析输入串和待匹配串是否相同.
 1 template<class T>
 2 class Ch : public Fail<T>
 3 {
 4 public:
 5     int Parser(T& s1,T s2)
 6     {
 7         Fail<T> t;
 8         if(s1.length >= s2.length)
 9             if(same(s1,s2))
10             {
11                 s1.start += s2.length;
12                 return s2.length;
13             }
14         return t.Parser(s1);
15     }
16 };
比如输入串为"abcdefg",匹配串为"abc",则Parser("abcdefg","abc")返回"abc"的长度3,如果匹配失败则返回0.

然后我们需要一个Seq,这个对象分析输入串和多个待匹配的连接串是否匹配,这里我们简单设为2个待匹配串.
 1 template<class T>
 2 class Seq : public Fail<T>
 3 {
 4 public:
 5     int Parser(T& s1,T s2,T s3)
 6     {
 7         Fail<T> t;
 8         Ch<T> ch1,ch2;
 9         int n1 = ch1.Parser(s1,s2);
10         int n2 = ch2.Parser(s1,s3);
11         if(n1 && n2) return n1 + n2;
12         else return t.Parser(s1);
13     }
14 };
比如输入串为"abcdefg",匹配串为"ab"和"cd",则Parser("abcdefg","ab","cd")返回"abcd"的长度4,如果匹配失败则返回0.

然后是Alt,这个对象分析输入串和多个待匹配串中的一个是否匹配,这里我们也简单的设为2个待匹配串.
 1 template<class T>
 2 class Alt : public Fail<T>
 3 {
 4 public:
 5     int Parser(T& s1,T s2,T s3)
 6     {
 7         Fail<T> t;
 8         Ch<T> ch1,ch2;
 9         int n1 = ch1.Parser(s1,s2);
10         int n2 = ch2.Parser(s1,s2);
11         if(n1) return n1;
12         else if(n2) return n2;
13         else return t.Parser(s1);
14     }
15 };
比如输入串为"abcdefg",匹配串为"ab"和"cd",则Parser("abcdefg","ab","cd")返回"ab"的长度2,如果匹配失败则返回0.

最后是Any,这个对象分析输入串和一个待匹配串的循环是否匹配.
 1 template<class T,int max>
 2 class Any : public Fail<T>
 3 {
 4 public:
 5     int Parser(T& s1,T s2)
 6     {
 7         Fail<T> t;
 8         for(int i=0;i<max;i++)
 9             if(!same(s1,s2))
10                 return t.Parser(s1);
11         return s2.length * max;
12     }
13 };
比如输入串为"ababefg",匹配串为"ab",max=2,则Parser("abcdefg","ab")返回"ab"的长度2*2,如果匹配失败则返回0.

然后我们来测试一下:
 1 void main()
 2 {
 3     Element s1;
 4     Element s2,s3;
 5     s1.data = new int[6];
 6     s1.length = 6;
 7     s1.data[0= 0;
 8     s1.data[1= 1;
 9     s1.data[2= 2;
10     s1.data[3= 3;
11     s1.data[4= 4;
12     s1.data[5= 5;
13     s2.data = new int[1];
14     s2.length = 1;
15     s2.data[0= 0;
16     s3.data = new int[1];
17     s3.length = 1;
18     s3.data[0= 1;
19     
20     // Seq Test
21     Seq<Element> seq;
22     int n = seq.Parser(s1,s2,s3);
23     printf("Seq is:%d\n",n);
24     
25     // Alt Test
26     s1.start = 0;
27     Alt<Element> alt;
28     n = alt.Parser(s1,s2,s3);
29     printf("Alt is:%d\n",n);
30     
31     // Any Test
32     s1.start = 0;
33     s1.data[1= 0;
34     Any<Element,2> any;
35     n = any.Parser(s1,s2);
36     printf("Any is:%d\n",n);
37     
38     delete[] s1.data;
39     delete[] s2.data;
40     delete[] s3.data;
41 }

结果为:
1 Seq is:2
2 Alt is:1
3 Any is:2

以上就是简单的面向组合子测试了.
posted on 2011-01-22 17:11 lwch 阅读(1566) 评论(4)  编辑 收藏 引用 所属分类: NScript

评论:
# re: 面向组合子的一些测试 2011-01-22 21:52 | 潍坊seo
可以交换个链接吗?  回复  更多评论
  
# re: 面向组合子的一些测试 2011-01-23 03:51 | 陈梓瀚(vczh)
还差一部分的精髓啊,你还是要试试看拿你这个东西做四则运算表达是分析器哈。  回复  更多评论
  
# re: 面向组合子的一些测试 2011-01-23 16:53 | lwch
@陈梓瀚(vczh)
的确..没有理解组合这个概念..  回复  更多评论
  
# re: 面向组合子的一些测试 2011-01-23 17:25 | 陈梓瀚(vczh)
@lwch
http://www.cppblog.com/vczh/archive/2010/04/28/113836.html

这个才是我用C++写的组合字。你看的那个是我用我大二的时候设计的一门动态语言写的。  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理