fork download
  1. #include <stdlib.h>
  2. #include <ctype.h>
  3.  
  4. /*
  5. commands:
  6.   EOF
  7.   |
  8.   command commands
  9.  
  10. command:
  11.   command_begin string command_end
  12.  
  13. string:
  14.   anything but command_end
  15.  
  16. command_begin:
  17.   QUOTE
  18.  
  19. command_end:
  20.   QUOTE SEMICOLON
  21.   |
  22.   QUOTE EOF
  23. */
  24.  
  25. struct iss_t
  26. {
  27. char* s;
  28. char* g;
  29. };
  30. typedef struct iss_t iss_t;
  31.  
  32. char iss_get_char( iss_t* self )
  33. {
  34. if ( !*self->g )
  35. return 0;
  36. return *self->g++;
  37. }
  38.  
  39. struct wschar_t
  40. {
  41. char c;
  42. char s[ 1024 ];
  43. };
  44. typedef struct wschar_t wschar_t;
  45.  
  46. char iss_get_wschar( iss_t* self, wschar_t* r )
  47. {
  48. char* p = r->s;
  49.  
  50. while ( isspace( *p++ = r->c = iss_get_char( self ) ) )
  51. ;
  52. *p = 0;
  53. return r->c;
  54. }
  55.  
  56. char iss_peek_wschar( iss_t* self )
  57. {
  58. char* savedg = self->g;
  59. wschar_t t;
  60. iss_get_wschar( self, &t );
  61. self->g = savedg;
  62. return t.c;
  63. }
  64.  
  65. enum token_t
  66. {
  67. tk_done,
  68. tk_beg,
  69. tk_end,
  70. tk_rest
  71. };
  72. typedef enum token_t token_t;
  73.  
  74. struct parser_t
  75. {
  76. iss_t* iss;
  77. wschar_t wschar;
  78. token_t token;
  79. };
  80. typedef struct parser_t parser_t;
  81.  
  82. token_t parser_get_token( parser_t* self )
  83. {
  84. iss_get_wschar( self->iss, &self->wschar );
  85.  
  86. // if done
  87. if ( self->wschar.c == 0 )
  88. return self->token = tk_done;
  89.  
  90. // not a quote
  91. if ( self->wschar.c != '\"' )
  92. return self->token = tk_rest;
  93.  
  94. // it is quote: check the next token
  95. switch ( iss_peek_wschar( self->iss ) )
  96. {
  97. case 0:
  98. case ';':
  99. iss_get_wschar( self->iss, &self->wschar ); // eat
  100. return self->token = tk_end;
  101. default:
  102. return self->token = tk_beg;
  103. }
  104. }
  105.  
  106. int parser_command( parser_t* self )
  107. {
  108. printf( "COMMAND: " );
  109. if ( self->token != tk_beg )
  110. {
  111. printf( "command begin expected" );
  112. return -1;
  113. }
  114.  
  115. while ( parser_get_token( self ) == tk_rest || self->token == tk_beg )
  116. printf( self->wschar.s );
  117.  
  118. if ( self->token != tk_end )
  119. {
  120. printf( "command end expected" );
  121. return -1;
  122. }
  123.  
  124. printf( "\n" );
  125.  
  126. return 0;
  127. }
  128.  
  129. void parser_commands( parser_t* self )
  130. {
  131. while ( 1 )
  132. {
  133. switch ( parser_get_token( self ) )
  134. {
  135.  
  136. case tk_done:
  137. return;
  138.  
  139. default:
  140. if ( parser_command( self ) < 0 )
  141. return;
  142.  
  143. };
  144. };
  145. }
  146.  
  147.  
  148. int main()
  149. {
  150. char* s = "\"command1\"; \"sleep 30; command2 -a ; command3\"; \"command4=\"MyTest\"\"";
  151. iss_t iss = { s, s };
  152. parser_t parser = { &iss };
  153. parser_commands( &parser );
  154.  
  155. return 0;
  156. }
  157.  
Success #stdin #stdout 0s 4448KB
stdin
Standard input is empty
stdout
COMMAND: command1
COMMAND: sleep 30; command2 -a ; command3
COMMAND: command4="MyTest"