PageRenderTime 52ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/src/gibbon-gmd-parser.y

#
Happy | 480 lines | 431 code | 49 blank | 0 comment | 0 complexity | cd29eaf16be05087b5b7a8757ebe819b MD5 | raw file
Possible License(s): LGPL-3.0, GPL-3.0
  1. /*
  2. * This file is part of gibbon.
  3. * Gibbon is a Gtk+ frontend for the First Internet Backgammon Server FIBS.
  4. * Copyright (C) 2009-2012 Guido Flohr, http://guido-flohr.net/.
  5. *
  6. * gibbon is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * gibbon is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with gibbon. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. /*
  20. * Parser for the internal format of Gibbon. The internal format is only
  21. * used for saving running matches. They are archived as SGF.
  22. */
  23. %{
  24. #ifdef HAVE_CONFIG_H
  25. # include "config.h"
  26. #endif
  27. #include <glib.h>
  28. #include <glib/gi18n.h>
  29. #include "gibbon-gmd-parser.h"
  30. #include "gibbon-gmd-reader-priv.h"
  31. #define reader gibbon_gmd_lexer_get_extra(scanner)
  32. /*
  33. * Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
  34. * as well as gratuitiously global symbol names, so we can have multiple
  35. * yacc generated parsers in the same program. Note that these are only
  36. * the variables produced by yacc. If other parser generators (bison,
  37. * byacc, etc) produce additional global names that conflict at link time,
  38. * then those parser generators need to be fixed instead of adding those
  39. * names to this list.
  40. */
  41. #define yymaxdepth gibbon_gmd_parser_maxdepth
  42. #define yyparse(s) gibbon_gmd_parser_parse(s)
  43. #define yylex gibbon_gmd_lexer_lex
  44. extern int gibbon_gmd_lexer_lex (YYSTYPE * lvalp, void *scanner);
  45. #define yyerror gibbon_gmd_reader_yyerror
  46. #define yylval gibbon_gmd_parser_lval
  47. #define yychar gibbon_gmd_parser_char
  48. #define yydebug gibbon_gmd_parser_debug
  49. #define yypact gibbon_gmd_parser_pact
  50. #define yyr1 gibbon_gmd_parser_r1
  51. #define yyr2 gibbon_gmd_parser_r2
  52. #define yydef gibbon_gmd_parser_def
  53. #define yychk gibbon_gmd_parser_chk
  54. #define yypgo gibbon_gmd_parser_pgo
  55. #define yyact gibbon_gmd_parser_act
  56. #define yyexca gibbon_gmd_parser_exca
  57. #define yyerrflag gibbon_gmd_parser_errflag
  58. #define yynerrs gibbon_gmd_parser_nerrs
  59. #define yyps gibbon_gmd_parser_ps
  60. #define yypv gibbon_gmd_parser_pv
  61. #define yys gibbon_gmd_parser_s
  62. #define yy_yys gibbon_gmd_parser_yys
  63. #define yystate gibbon_gmd_parser_state
  64. #define yytmp gibbon_gmd_parser_tmp
  65. #define yyv gibbon_gmd_parser_v
  66. #define yy_yyv gibbon_gmd_parser_yyv
  67. #define yyval gibbon_gmd_parser_val
  68. #define yylloc gibbon_gmd_parser_lloc
  69. #define yyreds gibbon_gmd_parser_reds /* With YYDEBUG defined */
  70. #define yytoks gibbon_gmd_parser_toks /* With YYDEBUG defined */
  71. #define yylhs gibbon_gmd_parser_yylhs
  72. #define yylen gibbon_gmd_parser_yylen
  73. #define yydefred gibbon_gmd_parser_yydefred
  74. #define yysdgoto gibbon_gmd_parser_yydgoto
  75. #define yysindex gibbon_gmd_parser_yysindex
  76. #define yyrindex gibbon_gmd_parser_yyrindex
  77. #define yygindex gibbon_gmd_parser_yygindex
  78. #define yytable gibbon_gmd_parser_yytable
  79. #define yycheck gibbon_gmd_parser_yycheck
  80. #define YYDEBUG 42
  81. %}
  82. %union {
  83. gint64 num;
  84. gdouble dbl;
  85. gchar *name;
  86. gint side;
  87. }
  88. %token MAGIC
  89. %token HYPHEN
  90. %token COLON
  91. %token <num> POSITIVE
  92. %token <num> INTEGER
  93. %token <name> NAME
  94. %token LENGTH
  95. %token PLAYER
  96. %token RANK
  97. %token LOCATION
  98. %token RULE
  99. %token CRAWFORD
  100. %token GAME
  101. %token WHITE
  102. %token BLACK
  103. %token NO_COLOR
  104. %token ROLL
  105. %token MOVE
  106. %token SLASH
  107. %token BAR
  108. %token HOME
  109. %token DOUBLE
  110. %token DROP
  111. %token TAKE
  112. %token RESIGN
  113. %token REJ
  114. %token ACCEPT
  115. %token UNKNOWN
  116. %token GARBAGE
  117. %token POINTS
  118. %token DICE
  119. %token SCORES
  120. %token CUBE
  121. %token TURN
  122. %token MAY_DOUBLE
  123. %token LBRACE RBRACE
  124. %type <side> color
  125. %type <num> movements
  126. %type <num> movement
  127. %type <num> point
  128. %type <num> die
  129. %type <num> score
  130. %pure-parser
  131. %lex-param {void *scanner}
  132. %parse-param {void *scanner}
  133. %%
  134. gmd_file
  135. : { yydebug = 0; } MAGIC HYPHEN POSITIVE things
  136. {
  137. _gibbon_gmd_reader_free_names (reader);
  138. }
  139. ;
  140. things
  141. : /* empty */
  142. | things thing
  143. {
  144. _gibbon_gmd_reader_free_names (reader);
  145. }
  146. ;
  147. thing
  148. : property
  149. | action
  150. ;
  151. property
  152. : length | player | rank | location | rule | game | unknown
  153. ;
  154. length
  155. : LENGTH COLON POSITIVE
  156. {
  157. _gibbon_gmd_reader_set_match_length (reader, $3);
  158. }
  159. ;
  160. player
  161. : PLAYER COLON color COLON NAME
  162. {
  163. _gibbon_gmd_reader_set_player (reader, $3, $5);
  164. }
  165. ;
  166. rank
  167. : RANK COLON color COLON NAME
  168. {
  169. _gibbon_gmd_reader_set_rank (reader, $3, $5);
  170. }
  171. ;
  172. location
  173. : LOCATION COLON NAME
  174. {
  175. _gibbon_gmd_reader_set_location (reader, $3);
  176. }
  177. ;
  178. game
  179. : GAME
  180. {
  181. if (!_gibbon_gmd_reader_add_game (reader))
  182. YYABORT;
  183. }
  184. COLON setups
  185. ;
  186. setups
  187. : /* empty */
  188. | setups setup
  189. /*
  190. * This is redundant as it will check for each component of the
  191. * setup. But this is so fast that there is no justification
  192. * to complicate the grammar for a more efficienct check
  193. * instead.
  194. */
  195. {
  196. if (!_gibbon_gmd_reader_check_setup (reader))
  197. YYABORT;
  198. }
  199. ;
  200. setup
  201. : points | dice | scores | cube | turn | may_double
  202. ;
  203. points
  204. : POINTS
  205. LBRACE
  206. point
  207. point point point point point point
  208. point point point point point point
  209. point point point point point point
  210. point point point point point point
  211. point
  212. {
  213. if (!_gibbon_gmd_reader_setup_position (reader, $3, $4, $5,
  214. $6, $7, $8, $9, $10,
  215. $11, $12, $13, $14,
  216. $15, $16, $17, $18,
  217. $19, $20, $21, $22,
  218. $23, $24, $25, $26,
  219. $27, $28))
  220. YYABORT;
  221. }
  222. RBRACE
  223. ;
  224. point
  225. : INTEGER
  226. {
  227. if ($1 < -15 || $1 > 15) {
  228. gibbon_gmd_reader_yyerror (scanner,
  229. _("Number of checkers on"
  230. " point out of range!"));
  231. YYABORT;
  232. }
  233. $$ = $1;
  234. }
  235. ;
  236. dice
  237. : DICE LBRACE die die
  238. {
  239. if (!_gibbon_gmd_reader_setup_dice (reader, $3, $4))
  240. YYABORT;
  241. }
  242. RBRACE
  243. ;
  244. die
  245. : INTEGER
  246. {
  247. if ($1 < -6 || $1 > 6 || $1 == 0) {
  248. gibbon_gmd_reader_yyerror (scanner,
  249. _("Invalid dice!"));
  250. YYABORT;
  251. }
  252. $$ = $1;
  253. }
  254. ;
  255. scores
  256. : SCORES LBRACE score score
  257. {
  258. if (!_gibbon_gmd_reader_setup_scores (reader, $3, $4))
  259. YYABORT;
  260. }
  261. RBRACE
  262. ;
  263. score
  264. : INTEGER
  265. {
  266. if ($1 < 0) {
  267. gibbon_gmd_reader_yyerror (scanner,
  268. _("Invalid score!"));
  269. YYABORT;
  270. }
  271. $$ = $1;
  272. }
  273. ;
  274. cube
  275. : CUBE LBRACE INTEGER
  276. {
  277. if (!_gibbon_gmd_reader_setup_cube (reader, $3,
  278. GIBBON_POSITION_SIDE_NONE))
  279. YYABORT;
  280. }
  281. RBRACE
  282. | CUBE LBRACE INTEGER INTEGER
  283. {
  284. if ($3 <= 0) {
  285. gibbon_gmd_reader_yyerror (scanner,
  286. _("Invalid cube!"));
  287. YYABORT;
  288. }
  289. if (!_gibbon_gmd_reader_setup_cube (reader, $3, $4))
  290. YYABORT;
  291. }
  292. RBRACE
  293. ;
  294. turn
  295. : TURN LBRACE INTEGER
  296. {
  297. if (!_gibbon_gmd_reader_setup_turn (reader, $3))
  298. YYABORT;
  299. }
  300. RBRACE
  301. ;
  302. may_double
  303. : MAY_DOUBLE LBRACE INTEGER INTEGER
  304. {
  305. if (!_gibbon_gmd_reader_setup_may_double (reader, $3, $4))
  306. YYABORT;
  307. }
  308. RBRACE
  309. rule
  310. : RULE COLON CRAWFORD
  311. {
  312. _gibbon_gmd_reader_set_crawford (reader);
  313. }
  314. | RULE COLON UNKNOWN
  315. ;
  316. action
  317. : roll | move | double | drop | take | resign | reject | accept
  318. ;
  319. color
  320. : BLACK { $$ = GIBBON_POSITION_SIDE_BLACK; }
  321. | WHITE { $$ = GIBBON_POSITION_SIDE_WHITE; }
  322. | NO_COLOR { $$ = GIBBON_POSITION_SIDE_NONE; }
  323. ;
  324. roll
  325. : ROLL COLON color COLON POSITIVE COLON POSITIVE POSITIVE
  326. {
  327. if (!_gibbon_gmd_reader_roll (reader, $3, $5, $7, $8))
  328. YYABORT;
  329. }
  330. ;
  331. move
  332. : MOVE COLON color COLON POSITIVE COLON movements
  333. {
  334. if (!_gibbon_gmd_reader_move (reader, $3, $5, $7))
  335. YYABORT;
  336. }
  337. ;
  338. movements
  339. : /* empty */
  340. {
  341. $$ = 0;
  342. }
  343. | movement /* $$ = $1 */
  344. | movement movement
  345. {
  346. $$ = $1 << 16 | $2;
  347. }
  348. | movement movement movement
  349. {
  350. $$ = $1 << 32 | $2 << 16 | $3;
  351. }
  352. | movement movement movement movement
  353. {
  354. $$ = $1 << 48 | $2 << 32 | $3 << 16 | $4;
  355. }
  356. ;
  357. movement
  358. : point SLASH point
  359. {
  360. $$ = ($1 << 8 | $3);
  361. }
  362. ;
  363. point
  364. : POSITIVE
  365. {
  366. if (!$$ || $$ > 24) {
  367. gibbon_gmd_reader_yyerror (scanner,
  368. _("Point out of"
  369. " range (1-24)!"));
  370. YYABORT;
  371. }
  372. }
  373. /*
  374. * These have to be decoded on a higher level with more
  375. * context available.
  376. */
  377. | HOME { $$ = 26; }
  378. | BAR { $$ = 27; }
  379. ;
  380. double
  381. : DOUBLE COLON color COLON POSITIVE
  382. {
  383. if (!_gibbon_gmd_reader_double (reader, $3, $5))
  384. YYABORT;
  385. }
  386. ;
  387. drop
  388. : DROP COLON color COLON POSITIVE
  389. {
  390. if (!_gibbon_gmd_reader_drop (reader, $3, $5))
  391. YYABORT;
  392. }
  393. ;
  394. take
  395. : TAKE COLON color COLON POSITIVE
  396. {
  397. if (!_gibbon_gmd_reader_take (reader, $3, $5))
  398. YYABORT;
  399. }
  400. ;
  401. resign
  402. : RESIGN COLON color COLON POSITIVE COLON POSITIVE
  403. {
  404. if (!$5) {
  405. yyerror (scanner,
  406. _("Resignation value cannot be"
  407. " zero!"));
  408. YYABORT;
  409. }
  410. if (!_gibbon_gmd_reader_resign (reader, $3, $5, $7))
  411. YYABORT;
  412. }
  413. ;
  414. reject
  415. : REJ COLON color COLON POSITIVE
  416. {
  417. if (!_gibbon_gmd_reader_reject (reader, $3, $5))
  418. YYABORT;
  419. }
  420. ;
  421. accept
  422. : ACCEPT COLON color COLON POSITIVE
  423. {
  424. if (!_gibbon_gmd_reader_accept (reader, $3, $5))
  425. YYABORT;
  426. }
  427. ;
  428. unknown
  429. : UNKNOWN COLON GARBAGE
  430. ;
  431. %%