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.
 
 
 
 
 
 

347 lines
5.3 KiB

  1. %{
  2. /*
  3. * toc_parse.y -- parser for toc files
  4. *
  5. * Copyright (C) 2004 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 "toc_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 Cdtext *cdtext = NULL;
  20. %}
  21. %start tocfile
  22. %union {
  23. long ival;
  24. char *sval;
  25. }
  26. %token <ival> NUMBER
  27. %token <sval> STRING
  28. /* global (header) */
  29. %token CATALOG
  30. %token <ival> CD_DA
  31. %token <ival> CD_ROM
  32. %token <ival> CD_ROM_XA
  33. /* track */
  34. %token TRACK
  35. %token <ival> AUDIO
  36. %token <ival> MODE1
  37. %token <ival> MODE1_RAW
  38. %token <ival> MODE2
  39. %token <ival> MODE2_FORM1
  40. %token <ival> MODE2_FORM2
  41. %token <ival> MODE2_FORM_MIX
  42. %token <ival> MODE2_RAW
  43. %token <ival> RW
  44. %token <ival> RW_RAW
  45. %token NO
  46. %token <ival> COPY
  47. %token <ival> PRE_EMPHASIS
  48. %token <ival> TWO_CHANNEL_AUDIO
  49. %token <ival> FOUR_CHANNEL_AUDIO
  50. %token ISRC
  51. %token SILENCE
  52. %token ZERO
  53. %token AUDIOFILE
  54. %token DATAFILE
  55. %token FIFO
  56. %token START
  57. %token PREGAP
  58. %token INDEX
  59. /* CD-TEXT */
  60. %token CD_TEXT
  61. %token LANGUAGE_MAP
  62. %token LANGUAGE
  63. %token <ival> TITLE
  64. %token <ival> PERFORMER
  65. %token <ival> SONGWRITER
  66. %token <ival> COMPOSER
  67. %token <ival> ARRANGER
  68. %token <ival> MESSAGE
  69. %token <ival> DISC_ID
  70. %token <ival> GENRE
  71. %token <ival> TOC_INFO1
  72. %token <ival> TOC_INFO2
  73. %token <ival> UPC_EAN
  74. %token <ival> ISRC
  75. %token <ival> SIZE_INFO
  76. %type <ival> disc_mode
  77. %type <ival> track_modes
  78. %type <ival> track_mode
  79. %type <ival> track_sub_mode
  80. %type <ival> track_set_flag
  81. %type <ival> track_clear_flag
  82. %type <ival> time
  83. %type <ival> cdtext_item
  84. %%
  85. tocfile
  86. : new_cd global_statements track_list
  87. ;
  88. new_cd
  89. : /* empty */ {
  90. cd = cd_init();
  91. cdtext = cd_get_cdtext(cd);
  92. }
  93. ;
  94. global_statements
  95. : /* empty */
  96. | global_statements global_statement
  97. ;
  98. global_statement
  99. : CATALOG STRING '\n' { cd_set_catalog(cd, $2); }
  100. | disc_mode '\n' { cd_set_mode(cd, $1); }
  101. | CD_TEXT '{' opt_nl language_map cdtext_langs '}' '\n'
  102. | error '\n'
  103. ;
  104. disc_mode
  105. : CD_DA
  106. | CD_ROM
  107. | CD_ROM_XA
  108. ;
  109. track_list
  110. : track
  111. | track_list track
  112. ;
  113. track
  114. : new_track track_def track_statements {
  115. while (2 > track_get_nindex(track))
  116. track_add_index(track, 0);
  117. }
  118. ;
  119. new_track
  120. : /* empty */ {
  121. track = cd_add_track(cd);
  122. cdtext = track_get_cdtext(track);
  123. /* add 0 index */
  124. track_add_index(track, 0);
  125. }
  126. ;
  127. track_def
  128. : TRACK track_modes '\n' { track_set_mode(track, $2); }
  129. ;
  130. track_modes
  131. : track_mode
  132. | track_mode track_sub_mode { track_set_sub_mode(track, $2); }
  133. ;
  134. track_mode
  135. : AUDIO
  136. | MODE1
  137. | MODE1_RAW
  138. | MODE2
  139. | MODE2_FORM1
  140. | MODE2_FORM2
  141. | MODE2_FORM_MIX
  142. | MODE2_RAW
  143. ;
  144. track_sub_mode
  145. : RW
  146. | RW_RAW
  147. ;
  148. track_statements
  149. : track_statement
  150. | track_statements track_statement
  151. ;
  152. track_statement
  153. : track_flags
  154. | ISRC STRING '\n' { track_set_isrc(track, $2); }
  155. | CD_TEXT '{' opt_nl cdtext_langs '}' '\n'
  156. | track_data
  157. | track_pregap
  158. | track_index
  159. | error '\n'
  160. ;
  161. track_flags
  162. : track_set_flag { track_set_flag(track, $1); }
  163. | track_clear_flag { track_clear_flag(track, $1); }
  164. ;
  165. track_set_flag
  166. : COPY '\n'
  167. | PRE_EMPHASIS '\n'
  168. | FOUR_CHANNEL_AUDIO '\n'
  169. ;
  170. track_clear_flag
  171. : NO PRE_EMPHASIS '\n' { $$ = $2; }
  172. | NO COPY '\n' { $$ = $2; }
  173. | TWO_CHANNEL_AUDIO '\n'
  174. ;
  175. track_data
  176. : zero_data time '\n' {
  177. if (NULL == track_get_filename(track))
  178. track_set_zero_pre(track, $2);
  179. else
  180. track_set_zero_post(track, $2);
  181. }
  182. | AUDIOFILE STRING time '\n' {
  183. track_set_filename(track, $2);
  184. track_set_start(track, $3);
  185. }
  186. | AUDIOFILE STRING time time '\n' {
  187. track_set_filename(track, $2);
  188. track_set_start(track, $3);
  189. track_set_length(track, $4);
  190. }
  191. | DATAFILE STRING '\n' {
  192. track_set_filename(track, $2);
  193. }
  194. | DATAFILE STRING time '\n' {
  195. track_set_filename(track, $2);
  196. track_set_start(track, $3);
  197. }
  198. | FIFO STRING time '\n' {
  199. track_set_filename(track, $2);
  200. track_set_start(track, $3);
  201. }
  202. ;
  203. zero_data
  204. : SILENCE
  205. | ZERO
  206. ;
  207. track_pregap
  208. : START '\n'
  209. | START time '\n' {
  210. track_add_index(track, $2);
  211. }
  212. | PREGAP time '\n' {
  213. track_set_zero_pre(track, $2);
  214. track_add_index(track, $2);
  215. }
  216. ;
  217. track_index
  218. : INDEX time '\n' { track_add_index(track, $2); }
  219. ;
  220. language_map
  221. : LANGUAGE_MAP '{' opt_nl languages '}' '\n'
  222. ;
  223. languages
  224. : language
  225. | languages language
  226. ;
  227. language
  228. : NUMBER ':' NUMBER opt_nl { /* not implemented */ }
  229. ;
  230. cdtext_langs
  231. : cdtext_lang
  232. | cdtext_langs cdtext_lang
  233. ;
  234. cdtext_lang
  235. : LANGUAGE NUMBER '{' opt_nl cdtext_defs '}' '\n'
  236. ;
  237. cdtext_defs
  238. : /* empty */
  239. | cdtext_defs cdtext_def
  240. ;
  241. cdtext_def
  242. : cdtext_item STRING '\n' {
  243. cdtext_set ($1, $2, cdtext);
  244. }
  245. | cdtext_item '{' bytes '}' '\n' {
  246. yyerror("binary CD-TEXT data not supported\n");
  247. }
  248. ;
  249. cdtext_item
  250. : TITLE
  251. | PERFORMER
  252. | SONGWRITER
  253. | COMPOSER
  254. | ARRANGER
  255. | MESSAGE
  256. | DISC_ID
  257. | GENRE
  258. | TOC_INFO1
  259. | TOC_INFO2
  260. | UPC_EAN
  261. | ISRC
  262. | SIZE_INFO
  263. ;
  264. bytes
  265. : /* empty */
  266. | bytes ',' NUMBER
  267. ;
  268. time
  269. : NUMBER
  270. | NUMBER ':' NUMBER ':' NUMBER { $$ = time_msf_to_frame($1, $3, $5); }
  271. ;
  272. opt_nl
  273. : /* empty */
  274. | '\n'
  275. ;
  276. %%
  277. /* lexer interface */
  278. extern int toc_lineno;
  279. extern int yydebug;
  280. extern FILE *toc_yyin;
  281. void yyerror (char *s)
  282. {
  283. fprintf(stderr, "%d: %s\n", toc_lineno, s);
  284. }
  285. Cd *toc_parse (FILE *fp)
  286. {
  287. toc_yyin = fp;
  288. yydebug = 0;
  289. if (0 == yyparse())
  290. return cd;
  291. return NULL;
  292. }