You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

285 line
4.5 KiB

  1. %{
  2. /*
  3. * cue_parse.y -- parser for cue files
  4. *
  5. * Copyright (C) 2004, 2005, 2006, 2007, 2013 Svend Sorensen
  6. * For license terms, see the file COPYING in this distribution.
  7. */
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include "cd.h"
  12. #include "time.h"
  13. #include "cue_parse_prefix.h"
  14. #define YYDEBUG 1
  15. extern int yylex();
  16. void yyerror (char *s);
  17. static Cd *cd = NULL;
  18. static Track *track = NULL;
  19. static Track *prev_track = NULL;
  20. static Cdtext *cdtext = NULL;
  21. static char *prev_filename = NULL; /* last file in or before last track */
  22. static char *cur_filename = NULL; /* last file in the last track */
  23. static char *new_filename = NULL; /* last file in this track */
  24. %}
  25. %start cuefile
  26. %union {
  27. long ival;
  28. char *sval;
  29. }
  30. %token <ival> NUMBER
  31. %token <sval> STRING
  32. /* global (header) */
  33. %token CATALOG
  34. %token CDTEXTFILE
  35. %token FFILE
  36. %token BINARY
  37. %token MOTOROLA
  38. %token AIFF
  39. %token WAVE
  40. %token MP3
  41. /* track */
  42. %token TRACK
  43. %token <ival> AUDIO
  44. %token <ival> MODE1_2048
  45. %token <ival> MODE1_2352
  46. %token <ival> MODE2_2336
  47. %token <ival> MODE2_2048
  48. %token <ival> MODE2_2342
  49. %token <ival> MODE2_2332
  50. %token <ival> MODE2_2352
  51. /* ISRC is with CD_TEXT */
  52. %token TRACK_ISRC
  53. %token FLAGS
  54. %token <ival> PRE
  55. %token <ival> DCP
  56. %token <ival> FOUR_CH
  57. %token <ival> SCMS
  58. %token PREGAP
  59. %token INDEX
  60. %token POSTGAP
  61. /* CD-TEXT */
  62. %token <ival> TITLE
  63. %token <ival> PERFORMER
  64. %token <ival> SONGWRITER
  65. %token <ival> COMPOSER
  66. %token <ival> ARRANGER
  67. %token <ival> MESSAGE
  68. %token <ival> DISC_ID
  69. %token <ival> GENRE
  70. %token <ival> TOC_INFO1
  71. %token <ival> TOC_INFO2
  72. %token <ival> UPC_EAN
  73. %token <ival> ISRC
  74. %token <ival> SIZE_INFO
  75. %type <ival> track_mode
  76. %type <ival> track_flag
  77. %type <ival> time
  78. %type <ival> cdtext_item
  79. %%
  80. cuefile
  81. : new_cd global_statements track_list
  82. ;
  83. new_cd
  84. : /* empty */ {
  85. cd = cd_init();
  86. cdtext = cd_get_cdtext(cd);
  87. }
  88. ;
  89. global_statements
  90. : /* empty */
  91. | global_statements global_statement
  92. ;
  93. global_statement
  94. : CATALOG STRING '\n' { cd_set_catalog(cd, $2); }
  95. | CDTEXTFILE STRING '\n' { /* ignored */ }
  96. | cdtext
  97. | track_data
  98. | error '\n'
  99. ;
  100. track_data
  101. : FFILE STRING file_format '\n' {
  102. if (NULL != new_filename) {
  103. yyerror("too many files specified\n");
  104. free(new_filename);
  105. }
  106. new_filename = strdup($2);
  107. }
  108. ;
  109. track_list
  110. : track
  111. | track_list track
  112. ;
  113. track
  114. : new_track track_def track_statements
  115. ;
  116. file_format
  117. : BINARY
  118. | MOTOROLA
  119. | AIFF
  120. | WAVE
  121. | MP3
  122. ;
  123. new_track
  124. : /*empty */ {
  125. /* save previous track, to later set length */
  126. prev_track = track;
  127. track = cd_add_track(cd);
  128. cdtext = track_get_cdtext(track);
  129. cur_filename = new_filename;
  130. if (NULL != cur_filename) {
  131. prev_filename = cur_filename;
  132. }
  133. if (NULL == prev_filename) {
  134. yyerror("no file specified for track");
  135. } else {
  136. track_set_filename(track, prev_filename);
  137. }
  138. new_filename = NULL;
  139. }
  140. ;
  141. track_def
  142. : TRACK NUMBER track_mode '\n' {
  143. track_set_mode(track, $3);
  144. }
  145. ;
  146. track_mode
  147. : AUDIO
  148. | MODE1_2048
  149. | MODE1_2352
  150. | MODE2_2336
  151. | MODE2_2048
  152. | MODE2_2342
  153. | MODE2_2332
  154. | MODE2_2352
  155. ;
  156. track_statements
  157. : track_statement
  158. | track_statements track_statement
  159. ;
  160. track_statement
  161. : cdtext
  162. | FLAGS track_flags '\n'
  163. | TRACK_ISRC STRING '\n' { track_set_isrc(track, $2); }
  164. | PREGAP time '\n' { track_set_zero_pre(track, $2); }
  165. | INDEX NUMBER time '\n' {
  166. int i = track_get_nindex(track);
  167. long prev_length;
  168. if (0 == i) {
  169. /* first index */
  170. track_set_start(track, $3);
  171. if (NULL != prev_track && NULL == cur_filename) {
  172. /* track shares file with previous track */
  173. prev_length = $3 - track_get_start(prev_track);
  174. track_set_length(prev_track, prev_length);
  175. }
  176. }
  177. for (; i <= $2; i++) {
  178. track_add_index(track, \
  179. track_get_zero_pre(track) + $3 \
  180. - track_get_start(track));
  181. }
  182. }
  183. | POSTGAP time '\n' { track_set_zero_post(track, $2); }
  184. | track_data
  185. | error '\n'
  186. ;
  187. track_flags
  188. : /* empty */
  189. | track_flags track_flag { track_set_flag(track, $2); }
  190. ;
  191. track_flag
  192. : PRE
  193. | DCP
  194. | FOUR_CH
  195. | SCMS
  196. ;
  197. cdtext
  198. : cdtext_item STRING '\n' { cdtext_set ($1, $2, cdtext); }
  199. ;
  200. cdtext_item
  201. : TITLE
  202. | PERFORMER
  203. | SONGWRITER
  204. | COMPOSER
  205. | ARRANGER
  206. | MESSAGE
  207. | DISC_ID
  208. | GENRE
  209. | TOC_INFO1
  210. | TOC_INFO2
  211. | UPC_EAN
  212. | ISRC
  213. | SIZE_INFO
  214. ;
  215. time
  216. : NUMBER
  217. | NUMBER ':' NUMBER ':' NUMBER { $$ = time_msf_to_frame($1, $3, $5); }
  218. ;
  219. %%
  220. /* lexer interface */
  221. extern int cue_lineno;
  222. extern int yydebug;
  223. extern FILE *cue_yyin;
  224. void yyerror (char *s)
  225. {
  226. fprintf(stderr, "%d: %s\n", cue_lineno, s);
  227. }
  228. Cd *cue_parse (FILE *fp)
  229. {
  230. cue_yyin = fp;
  231. yydebug = 0;
  232. if (0 == yyparse()) {
  233. return cd;
  234. }
  235. return NULL;
  236. }