3,881
社区成员
发帖
与我相关
我的任务
分享我只喜欢这样子的:
%{
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#if defined( _MSC_VER )
#define YY_NO_UNISTD_H
#endif
struct parser_context
{
char *input;
};
#define YYPARSE_PARAM parser
#define YYLEX_PARAM ((struct parser_context*)YYPARSE_PARAM)
union YYSTYPE;
int yylex ( union YYSTYPE* , struct parser_context* );
int yyparse ( void *YYPARSE_PARAM );
void yyerror( const char* msg ) {
fprintf( stderr , "[ERROR]--- %s ---\n" , msg );
}
%}
%pure_parser
%union {
int iVal;
char * sVal;
}
%token SUBSTR STRLEN I2A A2I
%token<iVal> NUMBER
%token<sVal> STRING
%type<iVal> iExpr
%type<sVal> sExpr
%destructor { free($$); } STRING sExpr
%left '+' '-'
%left '*' '/'
%right UADD USUB
%%
goal:
line
|
goal line
;
line:
iExpr '\n' { printf( "[INT]result = %d\n" , $1 ); }
|
sExpr '\n' { printf( "[STR]result = %s\n" , $1 ); free($1); }
|
'\n'
;
iExpr:
NUMBER
|
STRLEN '(' sExpr ')' { $$ = strlen( $3 ); free( $3 ); }
|
iExpr '+' iExpr { $$ = $1 + $3; }
|
iExpr '-' iExpr { $$ = $1 - $3; }
|
iExpr '*' iExpr { $$ = $1 * $3; }
|
iExpr '/' iExpr { if( $3 == 0 ) YYABORT; $$ = $1 / $3; }
|
'+' iExpr %prec UADD { $$ = $2 ; }
|
'-' iExpr %prec USUB { $$ = -$2; }
|
'(' iExpr ')' { $$ = $2; }
|
A2I '(' sExpr ')' { $$ = atoi( $3 ); free( $3 ); }
;
sExpr:
STRING
|
I2A '(' iExpr ')' { $$ = malloc( 16 ); sprintf( $$ , "%d" , $3 ); }
|
SUBSTR '(' sExpr ',' iExpr ',' iExpr ')' {
char *input = $3 , *result = NULL;
int beg = $5 , len = $7;
int slen = strlen( input );
if( beg < 0 ) beg = 0;
if( beg >= slen || len == 0 )
result = strdup( "" );
else if( len < 0 || beg + len >= slen )
result = strdup( input + beg );
else {
input[beg+len] = 0;
result = strdup( input + beg );
}
$$ = result;
free( input );
}
|
sExpr '+' sExpr {
$$ = malloc( strlen( $1 ) + strlen( $3 ) + 1 );
strcpy( $$ , $1 ); strcat( $$ , $3 ); free($1); free($3); }
|
'(' sExpr ')' { $$ = $2; }
;
%%
int main()
{
char line[ 32*1024 + 1 ] = "";
struct parser_context parser;
while( fgets( line , sizeof( line ) - 1 , stdin ) )
{
parser.input = line;
yyparse( &parser );
}
return 0;
}
int yylex ( union YYSTYPE* yylval , struct parser_context* parser )
{
char *input = parser->input;
char *text , *text_bak = NULL;
int curr , backup = 0 , action , yyc;
static const unsigned char yy_accept[33] =
{ 0,
0, 0, 11, 9, 8, 7, 7, 9, 5, 9,
9, 9, 8, 7, 0, 6, 5, 0, 0, 0,
0, 3, 4, 0, 0, 0, 0, 0, 0, 2,
1, 0
} ;
static const unsigned char yy_ec[256] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 2, 2, 3,
1, 2, 4, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 2, 1, 5, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 6, 6, 7,
6, 6, 6, 6, 6, 6, 6, 1, 1, 1,
1, 1, 1, 1, 8, 9, 1, 1, 10, 1,
1, 1, 11, 1, 1, 12, 1, 13, 1, 1,
1, 14, 15, 16, 17, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 8, 9, 1, 1,
10, 1, 1, 1, 11, 1, 1, 12, 1, 13,
1, 1, 1, 14, 15, 16, 17, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1
} ;
static const unsigned char yy_meta[18] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1
} ;
static const unsigned char yy_base[34] =
{ 0,
0, 0, 43, 44, 40, 44, 38, 35, 12, 32,
31, 4, 35, 44, 31, 30, 16, 23, 25, 18,
22, 44, 44, 18, 14, 18, 11, 13, 11, 44,
44, 44, 23
} ;
static const unsigned char yy_def[34] =
{ 0,
32, 1, 32, 32, 32, 32, 32, 33, 32, 32,
32, 32, 32, 32, 33, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 0, 32
} ;
static const unsigned char yy_nxt[62] =
{ 0,
4, 5, 6, 7, 8, 9, 9, 10, 4, 4,
11, 4, 4, 4, 12, 4, 4, 17, 17, 20,
21, 17, 17, 15, 31, 30, 29, 28, 27, 26,
25, 24, 23, 22, 15, 16, 13, 19, 18, 16,
14, 13, 32, 3, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32
} ;
static const unsigned char yy_chk[62] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 9, 9, 12,
12, 17, 17, 33, 29, 28, 27, 26, 25, 24,
21, 20, 19, 18, 16, 15, 13, 11, 10, 8,
7, 5, 3, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32
} ;
if( NULL == input )
return 0;
while( 1 )
{
if( 0 == input[0] )
{
parser->input = NULL;
return 0;
}
curr = 1;
text = input;
do {
if( 0 == input[0] )
break;
yyc = yy_ec[*(const unsigned char*)input++];
while( yy_chk[ yy_base[ curr ] + yyc ] != curr )
if( ( curr=yy_def[ curr ] ) >= sizeof(yy_accept)/sizeof(yy_accept[0]) )
yyc = yy_meta[ yyc ];
curr = yy_nxt[ yy_base[ curr ] + yyc ];
if( yy_accept[ curr ] )
{
backup = curr ;
text_bak = input;
}
} while( yy_base[curr] != yy_base[ sizeof(yy_accept)/sizeof(yy_accept[0]) - 1 ] );
action = yy_accept[ curr ];
if( 0 == action )
{
curr = backup;
input = text_bak;
action = yy_accept[ curr ];
}
parser->input = input;
switch( action )
{
case 1:
return SUBSTR;
case 2:
return STRLEN;
case 3:
return A2I;
case 4:
return I2A;
case 5:
yylval->iVal = atoi( text );
return NUMBER;
case 6:
{
char *p , *s;
s = text + 1;
input[-1] = 0;
p = yylval->sVal = (char*)malloc( input - text );
while( *s ) {
if( *s == '\"' && s[1] == 0 )
break;
if( *s == '\"' && s[1] == '\"' )
*p++ = '\"' , s += 2;
else
*p++ = *s++;
}
*p = 0;
return STRING;
}
case 7:
return '\n';
case 8:
break;
case 9:
return text[0];
}
}
return 0;
}
int main(void)
{
char result[1024] = {0};
sprintf(result, "%s", "\"hello\"+\" world\"+substr(\",nihaoma?\", 2, 3)\n");
yy_switch_to_buffer(yy_scan_string(result));
yyparse();
fread(result, sizeof(result), 1, yyout);
printf("%s\n", result);
return 0;
}
那些是flex生成的DFA状态表, 要包含处理结果, 就弄成这样:
%{
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#if defined( _MSC_VER )
#define YY_NO_UNISTD_H
#endif
struct parser_context
{
char *input;
int type ;
int iResult;
char* sResult;
};
#define YYPARSE_PARAM parser
#define YYLEX_PARAM ((struct parser_context*)YYPARSE_PARAM)
union YYSTYPE;
int yylex ( union YYSTYPE* , struct parser_context* );
int yyparse ( void *YYPARSE_PARAM );
void yyerror( const char* msg ) {
fprintf( stderr , "[ERROR]--- %s ---\n" , msg );
}
%}
%pure_parser
%union {
int iVal;
char * sVal;
}
%token SUBSTR STRLEN I2A A2I
%token<iVal> NUMBER
%token<sVal> STRING
%type<iVal> iExpr
%type<sVal> sExpr
%destructor { free($$); } STRING sExpr
%left '+' '-'
%left '*' '/'
%right UADD USUB
%%
goal:
line
|
goal line
;
line:
iExpr '\n' {
((struct parser_context*)YYPARSE_PARAM)->type = 0;
((struct parser_context*)YYPARSE_PARAM)->iResult = $1; }
|
sExpr '\n' {
((struct parser_context*)YYPARSE_PARAM)->type = 1;
((struct parser_context*)YYPARSE_PARAM)->sResult = $1; }
|
'\n'
;
iExpr:
NUMBER
|
STRLEN '(' sExpr ')' { $$ = strlen( $3 ); free( $3 ); }
|
iExpr '+' iExpr { $$ = $1 + $3; }
|
iExpr '-' iExpr { $$ = $1 - $3; }
|
iExpr '*' iExpr { $$ = $1 * $3; }
|
iExpr '/' iExpr { if( $3 == 0 ) YYABORT; $$ = $1 / $3; }
|
'+' iExpr %prec UADD { $$ = $2 ; }
|
'-' iExpr %prec USUB { $$ = -$2; }
|
'(' iExpr ')' { $$ = $2; }
|
A2I '(' sExpr ')' { $$ = atoi( $3 ); free( $3 ); }
;
sExpr:
STRING
|
I2A '(' iExpr ')' { $$ = malloc( 16 ); sprintf( $$ , "%d" , $3 ); }
|
SUBSTR '(' sExpr ',' iExpr ',' iExpr ')' {
char *input = $3 , *result = NULL;
int beg = $5 , len = $7;
int slen = strlen( input );
if( beg < 0 ) beg = 0;
if( beg >= slen || len == 0 )
result = strdup( "" );
else if( len < 0 || beg + len >= slen )
result = strdup( input + beg );
else {
input[beg+len] = 0;
result = strdup( input + beg );
}
$$ = result;
free( input );
}
|
sExpr '+' sExpr {
$$ = malloc( strlen( $1 ) + strlen( $3 ) + 1 );
strcpy( $$ , $1 ); strcat( $$ , $3 ); free($1); free($3); }
|
'(' sExpr ')' { $$ = $2; }
;
%%
int main()
{
char line[ 32*1024 + 1 ] = "";
struct parser_context parser;
while( fgets( line , sizeof( line ) - 1 , stdin ) )
{
parser.input = line;
if( 0 == yyparse( &parser ) ) {
if( parser.type == 0 ) {
printf( "[INT]result == %d\n" , parser.iResult );
}
else {
printf( "[STR]result == %s\n" , parser.sResult );
free( parser.sResult );
}
}
}
return 0;
}
int yylex ( union YYSTYPE* yylval , struct parser_context* parser )
{
char *input = parser->input;
char *text , *text_bak = NULL;
int curr , backup = 0 , action , yyc;
static const unsigned char yy_accept[33] =
{ 0,
0, 0, 11, 9, 8, 7, 7, 9, 5, 9,
9, 9, 8, 7, 0, 6, 5, 0, 0, 0,
0, 3, 4, 0, 0, 0, 0, 0, 0, 2,
1, 0
} ;
static const unsigned char yy_ec[256] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 2, 2, 3,
1, 2, 4, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 2, 1, 5, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 6, 6, 7,
6, 6, 6, 6, 6, 6, 6, 1, 1, 1,
1, 1, 1, 1, 8, 9, 1, 1, 10, 1,
1, 1, 11, 1, 1, 12, 1, 13, 1, 1,
1, 14, 15, 16, 17, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 8, 9, 1, 1,
10, 1, 1, 1, 11, 1, 1, 12, 1, 13,
1, 1, 1, 14, 15, 16, 17, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1
} ;
static const unsigned char yy_meta[18] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1
} ;
static const unsigned char yy_base[34] =
{ 0,
0, 0, 43, 44, 40, 44, 38, 35, 12, 32,
31, 4, 35, 44, 31, 30, 16, 23, 25, 18,
22, 44, 44, 18, 14, 18, 11, 13, 11, 44,
44, 44, 23
} ;
static const unsigned char yy_def[34] =
{ 0,
32, 1, 32, 32, 32, 32, 32, 33, 32, 32,
32, 32, 32, 32, 33, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 0, 32
} ;
static const unsigned char yy_nxt[62] =
{ 0,
4, 5, 6, 7, 8, 9, 9, 10, 4, 4,
11, 4, 4, 4, 12, 4, 4, 17, 17, 20,
21, 17, 17, 15, 31, 30, 29, 28, 27, 26,
25, 24, 23, 22, 15, 16, 13, 19, 18, 16,
14, 13, 32, 3, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32
} ;
static const unsigned char yy_chk[62] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 9, 9, 12,
12, 17, 17, 33, 29, 28, 27, 26, 25, 24,
21, 20, 19, 18, 16, 15, 13, 11, 10, 8,
7, 5, 3, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32
} ;
if( NULL == input )
return 0;
while( 1 )
{
if( 0 == input[0] )
{
parser->input = NULL;
return 0;
}
curr = 1;
text = input;
do {
if( 0 == input[0] )
break;
yyc = yy_ec[*(const unsigned char*)input++];
while( yy_chk[ yy_base[ curr ] + yyc ] != curr )
if( ( curr=yy_def[ curr ] ) >= sizeof(yy_accept)/sizeof(yy_accept[0]) )
yyc = yy_meta[ yyc ];
curr = yy_nxt[ yy_base[ curr ] + yyc ];
if( yy_accept[ curr ] )
{
backup = curr ;
text_bak = input;
}
} while( yy_base[curr] != yy_base[ sizeof(yy_accept)/sizeof(yy_accept[0]) - 1 ] );
action = yy_accept[ curr ];
if( 0 == action )
{
curr = backup;
input = text_bak;
action = yy_accept[ curr ];
}
parser->input = input;
switch( action )
{
case 1:
return SUBSTR;
case 2:
return STRLEN;
case 3:
return A2I;
case 4:
return I2A;
case 5:
yylval->iVal = atoi( text );
return NUMBER;
case 6:
{
char *p , *s;
s = text + 1;
input[-1] = 0;
p = yylval->sVal = (char*)malloc( input - text );
while( *s ) {
if( *s == '\"' && s[1] == 0 )
break;
if( *s == '\"' && s[1] == '\"' )
*p++ = '\"' , s += 2;
else
*p++ = *s++;
}
*p = 0;
return STRING;
}
case 7:
return '\n';
case 8:
break;
case 9:
return text[0];
}
}
return 0;
}
%{
%}
%option caseless
%%
substr { return SUBSTR; }
strlen { return STRLEN; }
a2i { return A2I; }
i2a { return I2A; }
[[:digit:]]+ { yylval.iVal = atoi( yytext ); return NUMBER; }
\"([^\"]|\"\")*\" {
char *p = yytext , *s = yytext + 1;
while( *s ) {
if( *s == '\"' && s[1] == 0 )
break;
if( *s == '\"' && s[1] == '\"' )
*p++ = '\"' , s += 2;
else
*p++ = *s++;
}
*p = 0;
yylval.sVal = strdup( yytext );
return STRING;}
\r\n|\r|\n { return '\n'; }
[ \t\b\f]+
. { return yytext[0]; }
%%
int yywrap()
{
return 1;
}
%{
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#if defined( _MSC_VER )
#define YY_NO_UNISTD_H
#endif
int yylex();
void yyerror( const char* msg ) {
fprintf( stderr , "[ERROR]--- %s ---\n" , msg );
}
%}
%union {
int iVal;
char * sVal;
}
%token SUBSTR STRLEN I2A A2I
%token<iVal> NUMBER
%token<sVal> STRING
%type<iVal> iExpr
%type<sVal> sExpr
%destructor { free($$); } STRING sExpr
%left '+' '-'
%left '*' '/'
%right UADD USUB
%%
goal:
line
|
goal line
;
line:
iExpr '\n' { printf( "[INT]result = %d\n" , $1 ); }
|
sExpr '\n' { printf( "[STR]result = %s\n" , $1 ); free($1); }
|
'\n'
;
iExpr:
NUMBER
|
STRLEN '(' sExpr ')' { $$ = strlen( $3 ); free( $3 ); }
|
iExpr '+' iExpr { $$ = $1 + $3; }
|
iExpr '-' iExpr { $$ = $1 - $3; }
|
iExpr '*' iExpr { $$ = $1 * $3; }
|
iExpr '/' iExpr { if( $3 == 0 ) YYABORT; $$ = $1 / $3; }
|
'+' iExpr %prec UADD { $$ = $2 ; }
|
'-' iExpr %prec USUB { $$ = -$2; }
|
'(' iExpr ')' { $$ = $2; }
|
A2I '(' sExpr ')' { $$ = atoi( $3 ); free( $3 ); }
;
sExpr:
STRING
|
I2A '(' iExpr ')' { $$ = malloc( 16 ); sprintf( $$ , "%d" , $3 ); }
|
SUBSTR '(' sExpr ',' iExpr ',' iExpr ')' {
char *input = $3 , *result = NULL;
int beg = $5 , len = $7;
int slen = strlen( input );
if( beg < 0 ) beg = 0;
if( beg >= slen || len == 0 )
result = strdup( "" );
else if( len < 0 || beg + len >= slen )
result = strdup( input + beg );
else {
input[beg+len] = 0;
result = strdup( input + beg );
}
$$ = result;
free( input );
}
|
sExpr '+' sExpr {
$$ = malloc( strlen( $1 ) + strlen( $3 ) + 1 );
strcpy( $$ , $1 ); strcat( $$ , $3 ); free($1); free($3); }
|
'(' sExpr ')' { $$ = $2; }
;
%%
#include "scanner.inl"
int main()
{
return yyparse();
}
1+2-3
[INT]result = 0
substr( "12312312" , 3 , 2 )
[STR]result = 12
"abc" + substr("efghijklmn", 0, 3) + "xyz"
[STR]result = abcefgxyz
substr(substr("efghijklmn", 0, 4), 0, 2)
[STR]result = ef
a2i( substr( substr(substr("efghijklmn", 1+2-3-1, 4), 0, 2) + "123" , 3 , 5 ) )
+ 10 * 2
[INT]result = 43
%{
#include <stdio.h>
#include <stdlib.h>
void yyerror(char*);
#include "cal.tab.h"
char buf[1024];
char* s;
char* removequote(char* s);
void substr(char *s, int pos, int count, char* substr);
%}
%x STRING
%%
"substr" return SUBSTR;
\"(\\.|[^\\"])*\" { strcpy(buf, yytext); yylval = removequote(yytext); return STR;}
[0-9]+ {yylval = strdup(yytext); return INT;}
"," return (',');
"(" return ('(');
")" return (')');
"+" return ('+');
[\n] return *yytext;
[\t] ;
. yyerror("invalid char\n");
%%
int yywrap(void)
{
return 1;
}
char* removequote(char* s)
{
char szValue[1024];
char szLine[1024];
int len;
len = strlen(s);
strcpy(szLine, s);
strcpy(szValue, &szLine[1]);
szValue[len - 2] = 0;
s = szValue;
return s;
}
void substr(char *s, int pos, int count, char* substr)
{
//printf("%s, %d, %d\n", s, pos, count);
//return s;
int len, i, j;
len = strlen(s);
for ( i = pos, j = 0; i < pos + count; )
substr[j++] = s[i++];
substr[j] = 0;
}
%{
int yylex(void);
void yyerror(char*);
char szTmp[1024];
%}
%token STR INT SUBSTR
%left '+'
%%
program:
program expr '\n' { printf("%s\n", $2); exit(0);}
|
;
expr:
STR {$$=$1;}
| SUBSTR '(' STR ',' INT ',' INT ')'
{
printf("$3=%s,$5=%s,$7=%s\n", $3, $5, $7);
substr($3, atoi($5), atoi($7), szTmp);
$$ = szTmp;
}
| expr '+' expr
{
printf("\n$1=%s, $3=%s\n", $1, $3);
strcat(szTmp, $1);
strcat(szTmp, $3);
$$ = szTmp;
}
;
%%
void yyerror(char *s)
{
fprintf(stderr, "%s\n", s);
return;
}
int main(void)
{
yyparse();
return 0;
}