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

完整代码:
#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 ;
}

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

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

你可能感兴趣的:(状态机)