Towards CUE parser via flex/bison.

This commit is contained in:
rocky
2003-05-11 03:29:25 +00:00
parent ffa4104620
commit 9a7cf3a4ee
8 changed files with 498 additions and 0 deletions

5
parse/.cvsignore Normal file
View File

@@ -0,0 +1,5 @@
cue.tab.c
cue.tab.h
cuelexer
cueparser
lex.cuelex.c

25
parse/Makefile Normal file
View File

@@ -0,0 +1,25 @@
all: cueparser cuelexer
lex.cue.c: cue.L cue.tab.h
flex -Pcue cue.L
lex.cuelex.c: cue.L cue.tab.h
flex -Pcuelex cue.L
lex.cue.o: lex.cue.c
gcc -g -Wall -c lex.cue.c
lex.cuelex.o: lex.cuelex.c
gcc -g -DSTANDALONE -Wall -c lex.cuelex.c
cue.tab.c: cue.y
bison -p cue -d cue.y
cue.tab.o: cue.tab.c cue.tab.h
gcc -g -Wall -DSTANDALONE -c cue.tab.c
cueparser: lex.cue.o cue.tab.o
gcc -g lex.cue.o cue.tab.o -lfl -o cueparser
cuelexer: lex.cuelex.o
gcc -g lex.cuelex.o -lfl -o cuelexer

224
parse/cue.L Normal file
View File

@@ -0,0 +1,224 @@
/* $Id: cue.L,v 1.1 2003/05/11 03:29:25 rocky Exp $ -*- C -*- */
/* CUE-sheet scanner */
%{
#undef yywrap
#ifdef STANDALONE
#include <stdio.h>
#endif
#include "cue.tab.h"
static int debug_lex=0;
%}
%x filename
TrackDef "TRACK"
Audio "AUDIO"
Mode1_2048 "MODE1/2048"
Mode1_2352 "MODE1/2352"
Mode2_2336 "MODE2/2336"
Mode2_2352 "MODE2/2352"
Index "INDEX"
File "FILE"
Pregap "PREGAP"
Postgap "POSTGAP"
Binary "BINARY"
Motorola "MOTOROLA"
Flags "FLAGS"
Catalog "CATALOG"
Isrc "ISRC"
Four_Channel "4CH"
Dont_Copy "DCP"
Pre_Emphasis "PRE"
Colon ":"
Integer [[:digit:]]+
Spaces [[:blank:]\n\r]+
String \".+\"
Filename [^[:blank:]\n\r]+
%%
{TrackDef} {
/*"*/
return TRACK_TOKEN;
}
{Audio} {
return AUDIO_TOKEN;
}
{Mode1_2048} {
return MODE1_2048_TOKEN;
}
{Mode1_2352} {
return MODE1_2352_TOKEN;
}
{Mode2_2336} {
return MODE2_2336_TOKEN;
}
{Mode2_2352} {
return MODE2_2352_TOKEN;
}
{Index} {
return INDEX_TOKEN;
}
{File} {
BEGIN(filename);
return FILE_TOKEN;
}
{Pregap} {
return PREGAP_TOKEN;
}
{Postgap} {
return POSTGAP_TOKEN;
}
{Binary} {
return BINARY_TOKEN;
}
{Motorola} {
return MOTOROLA_TOKEN;
}
{Flags} {
return FLAGS_TOKEN;
}
{Catalog} {
return CATALOG_TOKEN;
}
{Isrc} {
if (debug_lex) printf("Isrc token\n");
}
{Four_Channel} {
return FOURCH_TOKEN;
}
{Dont_Copy} {
return DCP_TOKEN;
}
{Pre_Emphasis} {
if (debug_lex) printf("Pre_Emphasis token\n");
}
{Colon} {
return COLON_TOKEN;
}
{Integer} {
return INTEGER_TOKEN;
}
<filename>{Filename} {
BEGIN(INITIAL);
return FILENAME_TOKEN;
}
<INITIAL,filename>{String} {
return STRING_TOKEN;
}
<INITIAL,filename>{Spaces} {
return SPACES_TOKEN;
}
<INITIAL,filename><<EOF>> {
return EOF;
}
%%
#if STANDALONE
int
main( int argc, const char **argv )
{
int token;
++argv, --argc; /* skip over program name */
debug_lex = 1;
if ( argc > 0 )
yyin = fopen( argv[0], "r" );
else
yyin = stdin;
while ((token=yylex()) != EOF) {
switch (token) {
case TRACK_TOKEN:
printf("TRACK\n");
break;
case AUDIO_TOKEN:
printf("AUDIO token\n");
break;
case MODE1_2048_TOKEN:
printf("MODE1/2048\n");
break;
case MODE1_2352_TOKEN:
printf("MODE1/2352\n");
break;
case MODE2_2336_TOKEN:
printf("MODE1/2336\n");
break;
case MODE2_2352_TOKEN:
printf("MODE2/2352\n");
break;
case INDEX_TOKEN:
printf("INDEX\n");
break;
case FILE_TOKEN:
printf("FILE\n");
break;
case PREGAP_TOKEN:
printf("PREGAP\n");
break;
case POSTGAP_TOKEN:
printf("POSTGAP\n");
break;
case BINARY_TOKEN:
printf("BINARY\n");
break;
case SPACES_TOKEN:
printf("spaces\n");
break;
case STRING_TOKEN:
printf("string: %s\n", yytext);
break;
case INTEGER_TOKEN:
printf("integer: %d (%s)\n", atoi(yytext), yytext);
break;
case COLON_TOKEN:
printf(":\n");
break;
case FLAGS_TOKEN:
printf("FLAGS\n");
break;
case CATALOG_TOKEN:
printf("CATALOG\n");
break;
case DCP_TOKEN:
printf("DCP\n");
break;
case MOTOROLA_TOKEN:
printf("MOTOROLA\n");
break;
case FOURCH_TOKEN:
printf("4CH\n");
break;
case FILENAME_TOKEN:
printf("filename %s\n", yytext);
break;
default: ;
}
}
return 0;
}
#endif

165
parse/cue.y Normal file
View File

@@ -0,0 +1,165 @@
%{
#include <stdio.h>
#include <stdlib.h>
extern FILE *cuein;
int cuelex(void);
int cueerror(char *s);
#ifdef STANDALONE
#include <getopt.h>
#define YYDEBUG 1
#endif
%}
/* BISON Declarations */
%token TRACK_TOKEN
%token AUDIO_TOKEN
%token MODE1_2048_TOKEN
%token MODE1_2352_TOKEN
%token MODE2_2336_TOKEN
%token MODE2_2352_TOKEN
%token INDEX_TOKEN
%token FILE_TOKEN
%token PREGAP_TOKEN
%token POSTGAP_TOKEN
%token BINARY_TOKEN
%token MOTOROLA_TOKEN
%token FLAGS_TOKEN
%token CATALOG_TOKEN
%token ISRC_TOKEN
%token FOURCH_TOKEN
%token DCP_TOKEN
%token PRE_TOKEN
%token COLON_TOKEN
%token INTEGER_TOKEN
%token SPACES_TOKEN
%token STRING_TOKEN
%token FILENAME_TOKEN
/* Grammar follows */
%%
/* We optionally allow spaces at the end of the file.
*/
cue: cue_stmts opt_spaces ;
/* one or more cuesheet statements. We allow spaces before the beginning
of the cuesheet statement */
cue_stmts: cue_stmts SPACES_TOKEN cue_stmt | opt_spaces cue_stmt ;
cue_stmt: catalog_stmt
| file_stmt
| track_stmt
| flags_stmt
| pregap_stmt
| postgap_stmt
| index_stmt
;
/* FILE *filename* {BINARY|MOTOROLA|AUDIO} */
file_stmt: FILE_TOKEN SPACES_TOKEN file_id SPACES_TOKEN file_flags
;
file_id: FILENAME_TOKEN | STRING_TOKEN
;
file_flags: BINARY_TOKEN | MOTOROLA_TOKEN | AUDIO_TOKEN
;
/* CATALOG *n* */
catalog_stmt: CATALOG_TOKEN INTEGER_TOKEN
;
/* TRACK *n* {MODE1/2048 | MODE1/2352 | MODE2/2336 | MODE2/2352} */
track_stmt: TRACK_TOKEN SPACES_TOKEN INTEGER_TOKEN SPACES_TOKEN track_mode_exp
;
track_mode_exp: MODE1_2048_TOKEN
| MODE1_2352_TOKEN
| MODE2_2336_TOKEN
| MODE2_2352_TOKEN
;
/* FLAGS {DCP | 4CH | PRE} */
flags_stmt: FLAGS_TOKEN SPACES_TOKEN flags_exp
;
flags_exp: DCP_TOKEN | FOURCH_TOKEN | PRE_TOKEN
;
/* PREGAP dd:dd:ddx */
pregap_stmt: PREGAP_TOKEN SPACES_TOKEN msf_exp
;
/* PROSTGAP dd:dd:dd */
postgap_stmt: POSTGAP_TOKEN SPACES_TOKEN msf_exp
;
/* INDEX *n* dd:dd:dd */
index_stmt: INDEX_TOKEN SPACES_TOKEN INTEGER_TOKEN SPACES_TOKEN msf_exp
;
/* a MSF e.g. 00:00:00 or 02:00 */
msf_exp: INTEGER_TOKEN COLON_TOKEN INTEGER_TOKEN COLON_TOKEN INTEGER_TOKEN
| INTEGER_TOKEN COLON_TOKEN INTEGER_TOKEN
;
opt_spaces: SPACES_TOKEN | ;
%%
#ifdef STANDALONE
/* The controlling function */
int
cueerror(char *s) /* called by cueparse on error */
{
printf("%s\n",s);
return(0);
}
int
main( int argc, char **argv )
{
int c;
cuedebug = 0;
while (1) {
int option_index = 0;
static struct option long_options[] = {
{"debug", 0, 0, 'd'},
{0, 0, 0, 0}
};
c = getopt_long (argc, argv, "d", long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 'd':
cuedebug = 1;
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
exit(1);
}
}
if ( optind < argc )
cuein = fopen( argv[optind], "r" );
else
cuein = stdin;
if (cueparse()==0) {
printf("Is a CUE file\n");
} else {
printf("Isn't a CUE file\n");
}
exit(0);
}
#endif /* STANDALONE*/

9
parse/test/t1.cue Normal file
View File

@@ -0,0 +1,9 @@
FILE "t1.bin" BINARY
TRACK 01 MODE2/2352
FLAGS DCP
INDEX 01 00:00:00
TRACK 02 MODE2/2352
FLAGS DCP
INDEX 00 00:04:00
INDEX 01 00:06:00
INDEX 02 00:06:32

10
parse/test/t2.cue Normal file
View File

@@ -0,0 +1,10 @@
FILE t2.bin AUDIO
TRACK 01 MODE1/2352
FLAGS DCP INDEX 01 00:00:00
TRACK 02 MODE1/2048
FLAGS DCP
INDEX 00 00:04:00
INDEX 01 00:06:00
INDEX 02 00:06:32

7
parse/test/t3.cue Normal file
View File

@@ -0,0 +1,7 @@
FILE BINARY BINARY
TRACK 01 MODE2/2352
FLAGS DCP
INDEX 01 00:00:00
TRACK 02 MODE2/2352
FLAGS DCP
INDEX 00 00:04:00 INDEX 01 00:06:93 INDEX 02 00:61:32