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.
 
 
 
 
 
 

350 lines
5.3 KiB

  1. %{
  2. /*
  3. * toc_parse.y -- parser for toc 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 "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. ;
  120. new_track
  121. : /* empty */ {
  122. track = cd_add_track(cd);
  123. cdtext = track_get_cdtext(track);
  124. /* add 0 index */
  125. track_add_index(track, 0);
  126. }
  127. ;
  128. track_def
  129. : TRACK track_modes '\n' { track_set_mode(track, $2); }
  130. ;
  131. track_modes
  132. : track_mode
  133. | track_mode track_sub_mode { track_set_sub_mode(track, $2); }
  134. ;
  135. track_mode
  136. : AUDIO
  137. | MODE1
  138. | MODE1_RAW
  139. | MODE2
  140. | MODE2_FORM1
  141. | MODE2_FORM2
  142. | MODE2_FORM_MIX
  143. | MODE2_RAW
  144. ;
  145. track_sub_mode
  146. : RW
  147. | RW_RAW
  148. ;
  149. track_statements
  150. : track_statement
  151. | track_statements track_statement
  152. ;
  153. track_statement
  154. : track_flags
  155. | ISRC STRING '\n' { track_set_isrc(track, $2); }
  156. | CD_TEXT '{' opt_nl cdtext_langs '}' '\n'
  157. | track_data
  158. | track_pregap
  159. | track_index
  160. | error '\n'
  161. ;
  162. track_flags
  163. : track_set_flag { track_set_flag(track, $1); }
  164. | track_clear_flag { track_clear_flag(track, $1); }
  165. ;
  166. track_set_flag
  167. : COPY '\n'
  168. | PRE_EMPHASIS '\n'
  169. | FOUR_CHANNEL_AUDIO '\n'
  170. ;
  171. track_clear_flag
  172. : NO PRE_EMPHASIS '\n' { $$ = $2; }
  173. | NO COPY '\n' { $$ = $2; }
  174. | TWO_CHANNEL_AUDIO '\n'
  175. ;
  176. track_data
  177. : zero_data time '\n' {
  178. if (NULL == track_get_filename(track)) {
  179. track_set_zero_pre(track, $2);
  180. } else {
  181. track_set_zero_post(track, $2);
  182. }
  183. }
  184. | AUDIOFILE STRING time '\n' {
  185. track_set_filename(track, $2);
  186. track_set_start(track, $3);
  187. }
  188. | AUDIOFILE STRING time time '\n' {
  189. track_set_filename(track, $2);
  190. track_set_start(track, $3);
  191. track_set_length(track, $4);
  192. }
  193. | DATAFILE STRING '\n' {
  194. track_set_filename(track, $2);
  195. }
  196. | DATAFILE STRING time '\n' {
  197. track_set_filename(track, $2);
  198. track_set_start(track, $3);
  199. }
  200. | FIFO STRING time '\n' {
  201. track_set_filename(track, $2);
  202. track_set_start(track, $3);
  203. }
  204. ;
  205. zero_data
  206. : SILENCE
  207. | ZERO
  208. ;
  209. track_pregap
  210. : START '\n'
  211. | START time '\n' {
  212. track_add_index(track, $2);
  213. }
  214. | PREGAP time '\n' {
  215. track_set_zero_pre(track, $2);
  216. track_add_index(track, $2);
  217. }
  218. ;
  219. track_index
  220. : INDEX time '\n' { track_add_index(track, $2); }
  221. ;
  222. language_map
  223. : LANGUAGE_MAP '{' opt_nl languages '}' '\n'
  224. ;
  225. languages
  226. : language
  227. | languages language
  228. ;
  229. language
  230. : NUMBER ':' NUMBER opt_nl { /* not implemented */ }
  231. ;
  232. cdtext_langs
  233. : cdtext_lang
  234. | cdtext_langs cdtext_lang
  235. ;
  236. cdtext_lang
  237. : LANGUAGE NUMBER '{' opt_nl cdtext_defs '}' '\n'
  238. ;
  239. cdtext_defs
  240. : /* empty */
  241. | cdtext_defs cdtext_def
  242. ;
  243. cdtext_def
  244. : cdtext_item STRING '\n' {
  245. cdtext_set ($1, $2, cdtext);
  246. }
  247. | cdtext_item '{' bytes '}' '\n' {
  248. yyerror("binary CD-TEXT data not supported\n");
  249. }
  250. ;
  251. cdtext_item
  252. : TITLE
  253. | PERFORMER
  254. | SONGWRITER
  255. | COMPOSER
  256. | ARRANGER
  257. | MESSAGE
  258. | DISC_ID
  259. | GENRE
  260. | TOC_INFO1
  261. | TOC_INFO2
  262. | UPC_EAN
  263. | ISRC
  264. | SIZE_INFO
  265. ;
  266. bytes
  267. : /* empty */
  268. | bytes ',' NUMBER
  269. ;
  270. time
  271. : NUMBER
  272. | NUMBER ':' NUMBER ':' NUMBER { $$ = time_msf_to_frame($1, $3, $5); }
  273. ;
  274. opt_nl
  275. : /* empty */
  276. | '\n'
  277. ;
  278. %%
  279. /* lexer interface */
  280. extern int toc_lineno;
  281. extern int yydebug;
  282. extern FILE *toc_yyin;
  283. void yyerror (char *s)
  284. {
  285. fprintf(stderr, "%d: %s\n", toc_lineno, s);
  286. }
  287. Cd *toc_parse (FILE *fp)
  288. {
  289. toc_yyin = fp;
  290. yydebug = 0;
  291. if (0 == yyparse()) {
  292. return cd;
  293. }
  294. return NULL;
  295. }