请大仙们帮小弟我看看这是什么代码呀,这是小弟我从libcue里面拿出来的,神奇的VC竟然可以编译
请大仙们帮我看看这是什么代码呀,这是我从libcue里面拿出来的,神奇的VC竟然可以编译
下面的代码是从cue_parser.y这个文件里面拿出来的,搞不懂,
下面的代码是从cue_parser.y这个文件里面拿出来的,搞不懂,
- C/C++ code
%{ /* * Copyright (c) 2004, 2005, 2006, 2007, Svend Sorensen * Copyright (c) 2009, 2010 Jochen Keil * For license terms, see the file COPYING in this distribution. */ #include <stdlib.h> #include <stdio.h> #include <string.h> #include "config.h" #include "cd.h" #include "time.h" #ifdef YY_BUF_SIZE #undef YY_BUF_SIZE #endif #define YY_BUF_SIZE 16384 #define YYDEBUG 1 char fnamebuf[PARSER_BUFFER]; /* debugging */ //int yydebug = 1; extern int yylineno; extern FILE* yyin; static Cd *cd = NULL; static Track *track = NULL; static Track *prev_track = NULL; static Cdtext *cdtext = NULL; static Rem *rem = NULL; static char *prev_filename = NULL; /* last file in or before last track */ static char *cur_filename = NULL; /* last file in the last track */ static char *new_filename = NULL; /* last file in this track */ /* lexer interface */ typedef struct yy_buffer_state* YY_BUFFER_STATE; int yylex(void); void yyerror(const char*); YY_BUFFER_STATE yy_scan_string(const char*); YY_BUFFER_STATE yy_create_buffer(FILE*, int); void yy_switch_to_buffer(YY_BUFFER_STATE); void yy_delete_buffer(YY_BUFFER_STATE); /* parser interface */ int yyparse(void); Cd *cue_parse_file(FILE *fp); Cd *cue_parse_string(const char*); %} %start cuefile %union { long ival; char *sval; } %token <ival> NUMBER %token <sval> STRING /* global (header) */ %token CATALOG %token CDTEXTFILE %token FFILE %token BINARY %token MOTOROLA %token AIFF %token WAVE %token MP3 /* track */ %token TRACK %token <ival> AUDIO %token <ival> MODE1_2048 %token <ival> MODE1_2352 %token <ival> MODE2_2336 %token <ival> MODE2_2048 %token <ival> MODE2_2342 %token <ival> MODE2_2332 %token <ival> MODE2_2352 /* ISRC is with CD_TEXT */ %token TRACK_ISRC %token FLAGS %token <ival> PRE %token <ival> DCP %token <ival> FOUR_CH %token <ival> SCMS %token PREGAP %token INDEX %token POSTGAP /* CD-TEXT */ %token <ival> TITLE %token <ival> PERFORMER %token <ival> SONGWRITER %token <ival> COMPOSER %token <ival> ARRANGER %token <ival> MESSAGE %token <ival> DISC_ID %token <ival> GENRE %token <ival> TOC_INFO1 %token <ival> TOC_INFO2 %token <ival> UPC_EAN %token <ival> ISRC %token <ival> SIZE_INFO %type <ival> track_mode %type <ival> track_flag %type <ival> time %type <ival> cdtext_item /* REM */ %type <ival> rem_item %token <ival> DATE %token <ival> REPLAYGAIN_ALBUM_GAIN %token <ival> REPLAYGAIN_ALBUM_PEAK %token <ival> REPLAYGAIN_TRACK_GAIN %token <ival> REPLAYGAIN_TRACK_PEAK %% cuefile : new_cd global_statements track_list ; new_cd : /* empty */ { cd = cd_init(); cdtext = cd_get_cdtext(cd); rem = cd_get_rem(cd); } ; global_statements : /* empty */ | global_statements global_statement ; global_statement : CATALOG STRING '\n' { cd_set_catalog(cd, $2); } | CDTEXTFILE STRING '\n' { cd_set_cdtextfile(cd, $2); } | cdtext | rem | track_data | error '\n' ; track_data : FFILE STRING file_format '\n' { if (NULL != new_filename) { yyerror("too many files specified\n"); } new_filename = strncpy(fnamebuf, $2, sizeof(fnamebuf)); new_filename[strlen(new_filename)] = '\0'; } ; track_list : track | track_list track ; track : new_track track_def track_statements ; file_format : BINARY | MOTOROLA | AIFF | WAVE | MP3 ; new_track : /*empty */ { /* save previous track, to later set length */ prev_track = track; track = cd_add_track(cd); cdtext = track_get_cdtext(track); rem = track_get_rem(track); cur_filename = new_filename; if (NULL != cur_filename) prev_filename = cur_filename; if (NULL == prev_filename) yyerror("no file specified for track"); else track_set_filename(track, prev_filename); new_filename = NULL; } ; track_def : TRACK NUMBER track_mode '\n' { track_set_mode(track, $3); } ; track_mode : AUDIO | MODE1_2048 | MODE1_2352 | MODE2_2336 | MODE2_2048 | MODE2_2342 | MODE2_2332 | MODE2_2352 ; track_statements : track_statement | track_statements track_statement ; track_statement : cdtext | rem | FLAGS track_flags '\n' | TRACK_ISRC STRING '\n' { track_set_isrc(track, $2); } | PREGAP time '\n' { track_set_zero_pre(track, $2); } | INDEX NUMBER time '\n' { int i = track_get_nindex(track); long prev_length; if (0 == i) { /* first index */ track_set_start(track, $3); if (NULL != prev_track && NULL == cur_filename) { /* track shares file with previous track */ prev_length = $3 - track_get_start(prev_track); track_set_length(prev_track, prev_length); } } for (; i <= $2; i++) track_add_index(track, \ track_get_zero_pre(track) + $3 \ - track_get_start(track)); } | POSTGAP time '\n' { track_set_zero_post(track, $2); } | track_data | error '\n' ; track_flags : /* empty */ | track_flags track_flag { track_set_flag(track, $2); } ; track_flag : PRE | DCP | FOUR_CH | SCMS ; cdtext : cdtext_item STRING '\n' { cdtext_set ($1, $2, cdtext); } ; cdtext_item : TITLE | PERFORMER | SONGWRITER | COMPOSER | ARRANGER | MESSAGE | DISC_ID | GENRE | TOC_INFO1 | TOC_INFO2 | UPC_EAN | ISRC | SIZE_INFO ; time : NUMBER | NUMBER ':' NUMBER ':' NUMBER { $$ = time_msf_to_frame($1, $3, $5); } ; rem : rem_item STRING '\n' { rem_set($1, $2, rem); } ; rem_item : DATE | REPLAYGAIN_ALBUM_GAIN | REPLAYGAIN_ALBUM_PEAK | REPLAYGAIN_TRACK_GAIN | REPLAYGAIN_TRACK_PEAK ; %% /* lexer interface */ void yyerror (const char *s) { fprintf(stderr, "%d: %s\n", yylineno, s); } Cd *cue_parse_file(FILE *fp) { YY_BUFFER_STATE buffer = NULL; yyin = fp; buffer = yy_create_buffer(yyin, YY_BUF_SIZE); yy_switch_to_buffer(buffer); if (0 == yyparse()) { yy_delete_buffer(buffer); return cd; } yy_delete_buffer(buffer); return NULL; } Cd *cue_parse_string(const char* string) { YY_BUFFER_STATE buffer = NULL; buffer = yy_scan_string(string); if (0 == yyparse()) { yy_delete_buffer(buffer); return cd; } yy_delete_buffer(buffer); if(cd) cd_delete(cd); return NULL; }