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.
 
 
 
 
 
 

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