通过状态机实现的一个配置读取函数

完整代码:
#include <stdio.h>
#include 
<string.h>
#include 
<stdlib.h>
#include 
<stdbool.h>

char IS_CHAR(char x)
{
    
return (x >= 'A' && x <= 'Z'|| (x >= 'a' && x <= 'z')? true:false;
}

char *strtrim(char *s)
{
    
char *= NULL,*right = s,*left = s;

    
while(isspace(*left)) left++;
    p 
= left;
    
while(*right != '\0') right++;
    
for(right--;isspace(*right);right--);
    
*(right+1= '\0';
    strcpy(s,p);
    
return s;
}

void parse_body(const char *s,
                
char *section,
                
char *key,
                
char *value)
{
    typedef 
enum _body_state body_state;
    
enum _body_state
    {
        STATE_NONE 
= 0,
        STATE_SECTION,
        STATE_KEY,
        STATE_SPLIT,
        STATE_IN_SECTION,
        STATE_VALUE,
        STATE_COMMENT
    };

    
char *p_section_start;
    
char *p_key_start;
    
char *p_value_start;

    
char *= NULL;

    body_state state 
= STATE_NONE;
    
char *tmp = (char*)malloc(strlen(s) + 1);
    memset(tmp,
'\0',strlen(s) + 1);
    strncpy(tmp,s,strlen(s));

    
for(p = tmp;
        
*!= '\0';
        p
++)
    {
        
switch(state)
        {
        
case STATE_NONE:
            
if(IS_CHAR(*p))
            {
                state 
= STATE_SECTION;
                p_section_start 
= p;
            }
            
if((*p) == '#')
            {
                state 
= STATE_COMMENT;
            }
            
break;
        
case STATE_COMMENT:
            
if(*== '\n')
            {
                state 
= STATE_NONE;
            }

            
break;
        
case STATE_SECTION:
            
if((*p) == '{')
            {
                
*= '\0';
                state 
= STATE_IN_SECTION;

            }

            
break;
        
case STATE_KEY:
            
if(*== '=')
            {
                
*= '\0';
                p_value_start 
= p+1;
                state 
= STATE_VALUE;
            }
            
break;
        
case STATE_VALUE:
            
if(*== ';')
            {
                
*= '\0';

                strtrim(p_section_start);
                strtrim(p_key_start);
                strtrim(p_value_start);
                
if(strcmp(p_section_start,section) == 0 &&
                   strcmp(p_key_start ,key) 
== 0)
                {
                    strcpy(value,p_value_start);
                }
                state 
= STATE_IN_SECTION;
            }
            
break;
        
case STATE_SPLIT:
            
if(IS_CHAR(*p))
            {
                state 
= STATE_VALUE;
            }
            
break;
        
case STATE_IN_SECTION:
            
if(IS_CHAR(*p))
            {
                p_key_start 
= p;
                state 
= STATE_KEY;
            }
            
if((*p) == '}')
            {
                state 
= STATE_NONE;
            }
            
break;
        }
    }

    free(tmp);
}

int main()
{
    
char value[16= {0};
    FILE 
*= NULL;
    
char *buff = NULL;
    fpos_t pos 
= 0;
    f 
= fopen("d:\\my.conf","r");
    fseek(f,
0,SEEK_END);
    fgetpos(f,
&pos);
    buff 
= (char*)malloc(pos);
    memset(buff,
0,pos);
    fseek(f,
0,SEEK_SET);
    fread(buff,pos,
1,f);


    parse_body(buff,
"people","name",value);
    printf(
"value:%s",value);

    free(buff);
    
return 0;
}

my.conf:


#test title
#
this is a comment
#

people
{
    name
=ligang;
    age
=20;
    sex
=1;
}

box
{
    widget
=20;
    height
=30;
    color
=blue;
}

seller
{
    n73 
=    590;
    N900 
=      1500;
}

学习了李先静老师的系统程序员成长计划,自己实现了个简单的状态机,感觉真是威力无穷啊。。

 配合词法树就可以实现词法解析处理了,嘿嘿,年底也可以写个简单的解释语言玩玩咯

posted @ 2010-11-10 22:55  飘啊飘  阅读(479)  评论(0编辑  收藏  举报