PageRenderTime 48ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 0ms

/CS/migrated/tags/R0_18_001/plugins/csstdldr/stdparse.y

#
Happy | 1088 lines | 978 code | 110 blank | 0 comment | 0 complexity | d1e4d453066f406e51df84c2a042b1c1 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, LGPL-2.0
  1. /*
  2. The Crystal Space map file parser definition
  3. Copyright (C) 2000 by Andrew Zabolotny <bit@eltech.ru>
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public
  6. License as published by the Free Software Foundation; either
  7. version 2 of the License, or (at your option) any later version.
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Library General Public License for more details.
  12. You should have received a copy of the GNU Library General Public
  13. License along with this library; if not, write to the Free
  14. Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. */
  16. %{ /* Startup C++ code */
  17. #include "cssysdef.h"
  18. #include "stdldr.h"
  19. #include "csutil/cscolor.h"
  20. #include "csgeom/math2d.h"
  21. #include "csgeom/math3d.h"
  22. #include "iengine.h"
  23. #include "itxtmgr.h"
  24. #include "isector.h"
  25. #include "ipolyset.h"
  26. #include "ipolygon.h"
  27. #include "ithing.h"
  28. #include "iportal.h"
  29. /* Define this to debug parser */
  30. //#define YYDEBUG 1
  31. /* yyparse is a member function */
  32. #define yyparse csStandardLoader::yyparse
  33. /* Provide detailed info about parse errors */
  34. #define YYERROR_VERBOSE 1
  35. /* Avoid some "signed vs unsigned comparison" warnings */
  36. #define sizeof (int)sizeof
  37. // More shortcuts
  38. #define TEX storage.tex
  39. #define CAMERA storage.camera
  40. #define PLANE storage.plane
  41. #define SECTOR storage.sector
  42. #define ABORTMSG \
  43. { yyerror ("loading error, aborting"); YYABORT; }
  44. #define YYERROR_EXTENDED(msg) \
  45. if (yychar == STRING) \
  46. { \
  47. msg = (char *) realloc(msg, size += 14 + strlen (yylval.string)); \
  48. sprintf (strchr (msg, 0), " (value = `%s')", yylval.string); \
  49. } \
  50. else if (yychar == NUMBER) \
  51. { \
  52. msg = (char *) realloc(msg, size += 14 + 20); \
  53. sprintf (strchr (msg, 0), " (value = `%g')", yylval.fval); \
  54. }
  55. %} /* Definition for all tokens */
  56. /* Tell Bison to build a table with all token names */
  57. %token_table
  58. /* We want a re-enterant parser */
  59. %pure_parser
  60. /* Define the top-level non-terminal symbol */
  61. %start input
  62. /* Possible values for tokens returned by yylex()
  63. * NOTE: We can't use csColor or csVector3 inside the union since classes
  64. * with constructors are not allowed there. However, if we carefully place
  65. * structure members, we can typecast our union to either of the above
  66. * types (see macros above)
  67. */
  68. %union
  69. {
  70. // Just a number
  71. float fval;
  72. // A integer number
  73. int ival;
  74. // A boolean value
  75. bool bval;
  76. // A string value
  77. char *string;
  78. // A color
  79. csPColor color;
  80. // A 2D point
  81. csPVector2 vect2;
  82. // A 3D point
  83. csPVector3 vect;
  84. // A transformation matrix
  85. csMatrix3 *matrix;
  86. // A transformation matrix/vector
  87. csStandardLoader::yystorage *transform;
  88. }
  89. /*
  90. Terminal symbols -- keywords
  91. The alphabetical order of these is not crucial, but doing so will
  92. cause less initialization work on the parser (during startup the
  93. list of keywords is QuickSort'ed). Thus it is still advisable to
  94. store them in alphabetical order here.
  95. WARNING: Max 256-3 tokens are allowed. More tokens would require
  96. slight changes to tokenizer. Currently only 130 are used.
  97. */
  98. %token KW_ACTION
  99. %token KW_ADD
  100. %token KW_ALPHA
  101. %token KW_ATTENUATION
  102. %token KW_BEZIER
  103. %token KW_CAMERA
  104. %token KW_CENTER
  105. %token KW_CIRCLE
  106. %token KW_CLIP
  107. %token KW_COLLECTION
  108. %token KW_COLOR
  109. %token KW_COLORS
  110. %token KW_CONVEX
  111. %token KW_COPY
  112. %token KW_CURVECENTER
  113. %token KW_CURVECONTROL
  114. %token KW_CURVESCALE
  115. %token KW_DETAIL
  116. %token KW_DITHER
  117. %token KW_DYNAMIC
  118. %token KW_F
  119. %token KW_FILE
  120. %token KW_FIRST
  121. %token KW_FIRST_LEN
  122. %token KW_FLATCOL
  123. %token KW_FOG
  124. %token KW_FOR_2D
  125. %token KW_FOR_3D
  126. %token KW_FORWARD
  127. %token KW_FRAME
  128. %token KW_GOURAUD
  129. %token KW_HALO
  130. %token KW_HEIGHTMAP
  131. %token KW_IDENTITY
  132. %token KW_KEY
  133. %token KW_KEYCOLOR
  134. %token KW_LEN
  135. %token KW_LIBRARY
  136. %token KW_LIGHT
  137. %token KW_LIGHTING
  138. %token KW_LIMB
  139. %token KW_MATERIAL
  140. %token KW_MATRIX
  141. %token KW_MIPMAP
  142. %token KW_MIRROR
  143. %token KW_MIXMODE
  144. %token KW_MOVE
  145. %token KW_MOVEABLE
  146. %token KW_MULTIPLY
  147. %token KW_MULTIPLY2
  148. %token KW_NODE
  149. %token KW_ORIG
  150. %token KW_PLANE
  151. %token KW_POLYGON
  152. %token KW_PORTAL
  153. %token KW_POSITION
  154. %token KW_RADIUS
  155. %token KW_ROT
  156. %token KW_ROT_X
  157. %token KW_ROT_Y
  158. %token KW_ROT_Z
  159. %token KW_SCALE
  160. %token KW_SCALE_X
  161. %token KW_SCALE_Y
  162. %token KW_SCALE_Z
  163. %token KW_SCRIPT
  164. %token KW_SECOND
  165. %token KW_SECOND_LEN
  166. %token KW_SECTOR
  167. %token KW_SKELETON
  168. %token KW_SKYDOME
  169. %token KW_SOUND
  170. %token KW_SOUNDS
  171. %token KW_SPRITE
  172. %token KW_SPRITE2D
  173. %token KW_START
  174. %token KW_STATBSP
  175. %token KW_STATIC
  176. %token KW_TEMPLATE
  177. %token KW_TERRAIN
  178. %token KW_TEX
  179. %token KW_TEXLEN
  180. %token KW_TEXMAP
  181. %token KW_TEXNR
  182. %token KW_TEXTURE
  183. %token KW_TEXTURES
  184. %token KW_TEXTURE_LIGHTING
  185. %token KW_TEXTURE_MIPMAP
  186. %token KW_TEXTURE_SCALE
  187. %token KW_TEX_SET
  188. %token KW_TEX_SET_SELECT
  189. %token KW_THING
  190. %token KW_TRANSFORM
  191. %token KW_TRANSPARENT
  192. %token KW_TRIANGLE
  193. %token KW_UPWARD
  194. %token KW_UV
  195. %token KW_UVA
  196. %token KW_UVEC
  197. %token KW_UV_SHIFT
  198. %token KW_V
  199. %token KW_VERTEX
  200. %token KW_VERTICES
  201. %token KW_VVEC
  202. %token KW_W
  203. %token KW_WORLD
  204. %token KW_ZFILL
  205. /* yes/no tokens */
  206. %token KW_yes
  207. %token KW_no
  208. /* light attenuation tokens */
  209. %token KW_none
  210. %token KW_linear
  211. %token KW_inverse
  212. %token KW_realistic
  213. /* This should be the last keyword.
  214. * It is used to check the version of tokenized binary files
  215. */
  216. %token PARSER_VERSION
  217. /* Terminal symbols not recognized as keywords by yylex() */
  218. %token <string> STRING /* A string ('string' or without quotes) */
  219. %token <fval> NUMBER /* A floating-point number */
  220. /* Non-terminal symbol types */
  221. %type <string> name
  222. %type <ival> yesno
  223. %type <ival> yesno_onearg
  224. %type <color> color
  225. %type <vect> vect_idx
  226. %type <vect> vector
  227. %type <vect2> vector2
  228. %type <matrix> matrix
  229. %type <transform> move
  230. %% /* Grammar */
  231. /*-- Input stream ------------------------------------------------------------*/
  232. input:
  233. KW_WORLD name '('
  234. { engine->SelectLibrary (storage.cur_library = $2); }
  235. world_ops ')'
  236. | KW_LIBRARY name '('
  237. { engine->SelectLibrary (storage.cur_library = $2); }
  238. world_ops ')'
  239. ;
  240. /*-- Grammar -----------------------------------------------------------------*/
  241. world_ops:
  242. /* empty world */
  243. | world_ops world_op
  244. ;
  245. world_op:
  246. KW_TEXTURES '(' textures ')'
  247. | KW_TEX_SET name '('
  248. { storage.tex_prefix = $2; }
  249. textures ')'
  250. { storage.tex_prefix = NULL; }
  251. | KW_LIBRARY '(' STRING ')'
  252. { if (!RecursiveLoad ($3)) YYABORT; }
  253. | KW_SOUNDS '(' sounds ')'
  254. { printf ("SOUNDS\n"); }
  255. | KW_START '(' STRING ',' vector ')'
  256. {
  257. if (!engine->CreateCamera ("Start", $3,
  258. (csVector3 &)$5, csVector3 (0, 0, 1), csVector3 (0, 1, 0)))
  259. YYABORT;
  260. }
  261. | KW_CAMERA name '('
  262. { InitCamera ($2); }
  263. camera_ops ')'
  264. { if (!CreateCamera ()) YYABORT; }
  265. | KW_PLANE name '('
  266. {
  267. PLANE.mode = pmNONE;
  268. polygon.first_len = polygon.second_len = 0.0;
  269. }
  270. plane_ops ')'
  271. { if (!CreatePlane ($2)) YYABORT; }
  272. | KW_SECTOR name '('
  273. {
  274. SECTOR.object = engine->CreateSector ($2);
  275. SECTOR.polyset = QUERY_INTERFACE (SECTOR.object, iPolygonSet);
  276. SECTOR.texname = NULL;
  277. SECTOR.texlen = 1.0;
  278. SECTOR.statbsp = false;
  279. }
  280. sector_ops ')'
  281. {
  282. SECTOR.polyset->CompressVertices ();
  283. if (SECTOR.statbsp) SECTOR.object->CreateBSP ();
  284. SECTOR.polyset->DecRef ();
  285. }
  286. | KW_KEY STRING '(' STRING ')'
  287. { if (!engine->CreateKey ($2, $4)) ABORTMSG; }
  288. | KW_COLLECTION name '(' collection_ops ')'
  289. { printf ("COLLECTION [%s]\n", $2); }
  290. | KW_SCRIPT name '(' STRING ':' STRING ')'
  291. { printf ("SCRIPT '%s' (%s: %s)\n", $2, $4, $6); }
  292. | KW_THING name '(' thing_tpl_ops ')'
  293. { printf ("THING_tpl [%s]\n", $2); }
  294. | KW_SPRITE name '(' sprite_tpl_ops ')'
  295. { printf ("SPRITE [%s]\n", $2); }
  296. ;
  297. /*--------*/
  298. textures:
  299. /* empty */
  300. | textures texture
  301. ;
  302. texture:
  303. KW_TEXTURE name '('
  304. { InitTexture ($2); }
  305. texture_ops ')'
  306. { if (!CreateTexture ()) ABORTMSG; }
  307. ;
  308. texture_ops:
  309. /* empty */
  310. | texture_ops texture_op
  311. ;
  312. texture_op:
  313. KW_MIPMAP yesno_onearg
  314. {
  315. if ($2)
  316. TEX.flags = (TEX.flags & ~CS_TEXTURE_NOMIPMAPS);
  317. else
  318. TEX.flags |= CS_TEXTURE_NOMIPMAPS;
  319. }
  320. | KW_DITHER yesno_onearg
  321. {
  322. if ($2)
  323. TEX.flags |= CS_TEXTURE_DITHER;
  324. else
  325. TEX.flags = (TEX.flags & ~CS_TEXTURE_DITHER);
  326. }
  327. | KW_FILE '(' STRING ')'
  328. { TEX.filename = $3; }
  329. | KW_TRANSPARENT '(' color ')'
  330. { TEX.transp = $3; TEX.do_transp = true; }
  331. | KW_FOR_3D yesno_onearg
  332. {
  333. if ($2)
  334. TEX.flags |= CS_TEXTURE_3D;
  335. else
  336. TEX.flags = (TEX.flags & ~CS_TEXTURE_3D);
  337. }
  338. | KW_FOR_2D yesno_onearg
  339. {
  340. if ($2)
  341. TEX.flags |= CS_TEXTURE_2D;
  342. else
  343. TEX.flags = (TEX.flags & ~CS_TEXTURE_2D);
  344. }
  345. ;
  346. /*--------*/
  347. sounds:
  348. /* empty */
  349. | sounds sound
  350. ;
  351. sound:
  352. KW_SOUND name '(' sound_ops ')'
  353. ;
  354. sound_ops:
  355. /* empty */
  356. | sound_ops sound_op
  357. ;
  358. sound_op:
  359. KW_FILE '(' STRING ')' { printf ("FILE (%s)\n", $3); }
  360. ;
  361. /*--------*/
  362. sector_ops:
  363. sector_op
  364. | sector_ops sector_op
  365. ;
  366. sector_op:
  367. KW_VERTEX '(' vector ')'
  368. { SECTOR.polyset->CreateVertex (CSVECTOR3 ($3)); }
  369. | KW_POLYGON name '('
  370. {
  371. polygon.object = SECTOR.polyset->CreatePolygon ($2);
  372. polygon.texname = SECTOR.texname;
  373. polygon.texlen = SECTOR.texlen;
  374. }
  375. polygon_ops ')'
  376. | KW_TEXNR '(' STRING ')'
  377. { SECTOR.texname = $3; }
  378. | KW_TEXLEN '(' NUMBER ')'
  379. { SECTOR.texlen = $3; }
  380. | KW_STATBSP yesno_onearg
  381. { SECTOR.statbsp = $2; }
  382. | KW_THING name '('
  383. {
  384. thing.object = engine->CreateThing ($2, SECTOR.object);
  385. thing.polyset = QUERY_INTERFACE (thing.object, iPolygonSet);
  386. thing.texname = NULL;
  387. thing.texlen = 1.0;
  388. }
  389. thing_ops ')'
  390. {
  391. thing.polyset->DecRef ();
  392. }
  393. | KW_LIGHT name '(' light_ops ')'
  394. { printf ("LIGHT '%s' (...)\n", $2); }
  395. | KW_SPRITE name '(' sprite_ops ')'
  396. { printf ("SPRITE '%s' (...)\n", $2); }
  397. | KW_FOG '(' color NUMBER ')'
  398. { printf ("FOG (%g,%g,%g : %g)\n", $3.red, $3.green, $3.blue, $4); }
  399. | KW_CIRCLE '(' vector ':' vector NUMBER ')'
  400. /* <coordinate> ':' <radius> <num-verts> */
  401. { printf ("CIRCLE (...)\n"); }
  402. | KW_SKYDOME '(' skydome_ops ')'
  403. { printf ("SKYDOME (...)\n"); }
  404. | KW_KEY STRING '(' STRING ')'
  405. { if (!SECTOR.polyset->CreateKey ($2, $4)) ABORTMSG; }
  406. | KW_NODE '(' node_ops ')'
  407. { printf ("NODE (...)\n"); }
  408. ;
  409. skydome_ops:
  410. skydome_op
  411. | skydome_ops skydome_op
  412. ;
  413. skydome_op:
  414. KW_RADIUS '(' NUMBER ')'
  415. { printf ("RADIUS (%g)\n", $3); }
  416. | KW_VERTICES '(' vertex_indices ')'
  417. { printf ("VERTICES (...)\n"); }
  418. | KW_LIGHTING yesno_onearg
  419. { printf ("LIGHTING (%d)\n", $2); }
  420. ;
  421. vertex_indices:
  422. /* none */
  423. | vertex_indices NUMBER
  424. { }
  425. ;
  426. node_ops:
  427. node_op
  428. | node_ops node_op
  429. ;
  430. node_op:
  431. KW_POSITION '(' vector ')'
  432. { printf ("POSITION (...)\n"); }
  433. | KW_KEY '(' STRING ',' STRING ')'
  434. { printf ("KEY ('%s', '%s')\n", $3, $5); }
  435. ;
  436. /*--------*/
  437. plane_ops:
  438. plane_op
  439. | plane_ops plane_op
  440. ;
  441. plane_op:
  442. KW_ORIG '(' vect_idx ')'
  443. {
  444. PLANE.mode |= pmORIGIN;
  445. PLANE.origin.Set ($3);
  446. }
  447. | KW_FIRST '(' vect_idx ')'
  448. {
  449. PLANE.mode |= pmFIRSTSECOND;
  450. PLANE.first.Set ($3);
  451. }
  452. | KW_SECOND '(' vect_idx ')'
  453. {
  454. PLANE.mode |= pmFIRSTSECOND;
  455. PLANE.second.Set ($3);
  456. }
  457. | KW_FIRST_LEN '(' NUMBER ')'
  458. {
  459. PLANE.mode |= pmFIRSTSECOND;
  460. PLANE.first_len = $3;
  461. }
  462. | KW_SECOND_LEN '(' NUMBER ')'
  463. {
  464. PLANE.mode |= pmFIRSTSECOND;
  465. PLANE.second_len = $3;
  466. }
  467. | KW_UVEC '(' vector ')'
  468. {
  469. PLANE.mode |= pmVECTORS;
  470. PLANE.first = $3;
  471. PLANE.first_len = 1.0;
  472. }
  473. | KW_VVEC '(' vector ')'
  474. {
  475. PLANE.mode |= pmVECTORS;
  476. PLANE.second = $3;
  477. PLANE.second_len = 1.0;
  478. }
  479. | KW_MATRIX '(' matrix ')'
  480. {
  481. PLANE.mode |= pmMATRIX;
  482. PLANE.matrix.Set (*$3);
  483. }
  484. | KW_V '(' vector ')'
  485. {
  486. PLANE.mode |= pmMATRIX;
  487. PLANE.origin.Set ($3);
  488. }
  489. ;
  490. /*--------*/
  491. light_ops:
  492. light_op
  493. | light_ops light_op
  494. ;
  495. light_op:
  496. vector ':' NUMBER color NUMBER
  497. /* <pos> <radius> <color> <dynamic-flag> */
  498. { printf ("<pos> <radius> <color> <dynamic-flag>\n"); }
  499. | KW_CENTER '(' vector ')'
  500. { printf ("CENTER (...)\n"); }
  501. | KW_RADIUS '(' NUMBER ')'
  502. { printf ("RADIUS (%g)\n", $3); }
  503. | KW_DYNAMIC yesno_onearg
  504. { printf ("DYNAMIC (%d)\n", $2); }
  505. | KW_COLOR '(' color ')'
  506. { printf ("COLOR ( ... )\n"); }
  507. | KW_HALO '(' NUMBER NUMBER ')'
  508. { printf ("HALO (%g,%g)\n", $3, $4); }
  509. | KW_ATTENUATION '(' attenuation_op ')'
  510. ;
  511. attenuation_op:
  512. KW_none
  513. | KW_linear
  514. | KW_inverse
  515. | KW_realistic
  516. ;
  517. /*--------*/
  518. collection_ops:
  519. collection_op
  520. | collection_ops collection_op
  521. ;
  522. collection_op:
  523. KW_THING '(' STRING ')'
  524. { printf ("THING ('%s')\n", $3); }
  525. | KW_COLLECTION '(' STRING ')'
  526. { printf ("COLLECTION ('%s')\n", $3); }
  527. | KW_LIGHT '(' STRING ',' NUMBER ')'
  528. { printf ("LIGHT ('%s':%g)\n", $3, $5); }
  529. | KW_SECTOR '(' STRING ')'
  530. { printf ("SECTOR ('%s')\n", $3); }
  531. ;
  532. /*--------*/
  533. thing_tpl_ops:
  534. thing_tpl_op
  535. | thing_tpl_ops thing_tpl_op
  536. ;
  537. thing_tpl_op:
  538. KW_POLYGON name '('
  539. {
  540. polygon.object = thing.polyset->CreatePolygon ($2);
  541. polygon.texname = thing.texname;
  542. polygon.texlen = thing.texlen;
  543. }
  544. polygon_ops ')'
  545. | KW_VERTEX '(' vector ')'
  546. { thing.polyset->CreateVertex (CSVECTOR3 ($3)); }
  547. | KW_TEXNR '(' STRING ')'
  548. { thing.texname = $3; }
  549. | KW_TEXLEN '(' NUMBER ')'
  550. { thing.texlen = $3; }
  551. | KW_MOVE '(' move ')'
  552. {
  553. if ($3->matrix_valid)
  554. thing.object->SetTransform (CSMATRIX3 ($3->matrix));
  555. if ($3->vector_valid)
  556. thing.object->SetPosition (CSVECTOR3 ($3->vector));
  557. }
  558. | KW_FOG '(' color NUMBER ')'
  559. { printf ("FOG (%g,%g,%g : %g)\n", $3.red, $3.green, $3.blue, $4); }
  560. | KW_CONVEX yesno_onearg
  561. { printf ("CONVEX (%d)\n", $2); }
  562. | KW_CIRCLE '(' vector ':' vector NUMBER ')'
  563. /* <coordinate> ':' <radius> <num-verts> */
  564. { printf ("CIRCLE (...)\n"); }
  565. | KW_BEZIER name '(' bezier_ops ')'
  566. { printf ("BEZIER '%s' (...)\n", $2); }
  567. | KW_CURVECENTER '(' vector ')'
  568. { printf ("CURVECENTER (...)\n"); }
  569. | KW_CURVESCALE '(' NUMBER ')'
  570. { printf ("CURVESCALE (%g)\n", $3); }
  571. | KW_CURVECONTROL '(' vector ':' vector2 ')'
  572. { printf ("CURVECONTROL (...)\n"); }
  573. ;
  574. thing_ops:
  575. thing_op
  576. | thing_ops thing_op
  577. ;
  578. thing_op:
  579. thing_tpl_op
  580. | KW_KEY '(' STRING ',' STRING ')'
  581. { printf ("KEY ('%s', '%s')\n", $3, $5); }
  582. | KW_TEMPLATE '(' STRING ')'
  583. { printf ("TEMPLATE ('%s')\n", $3); }
  584. | KW_MOVEABLE yesno_onearg
  585. { printf ("MOVEABLE (%d)\n", $2); }
  586. | KW_TEX_SET_SELECT '(' STRING ')'
  587. { printf ("TEX_SET_SELECT ('%s')\n", $3); }
  588. | KW_FILE '(' STRING ')'
  589. { printf ("FILE ('%s')\n", $3); }
  590. ;
  591. /*--------*/
  592. bezier_ops:
  593. bezier_op
  594. | bezier_ops bezier_op
  595. ;
  596. bezier_op:
  597. KW_TEXNR '(' STRING ')'
  598. { printf ("TEXNR (%s)\n", $3); }
  599. | KW_TEXTURE '(' bezier_texture_ops ')'
  600. { printf ("TEXTURE (...)\n"); }
  601. | KW_VERTICES '(' vertex_indices ')'
  602. { printf ("VERTICES (...)\n"); }
  603. ;
  604. bezier_texture_ops:
  605. bezier_texture_op
  606. | bezier_texture_ops bezier_texture_op
  607. ;
  608. bezier_texture_op:
  609. /* unused op for now */
  610. "unused"
  611. ;
  612. /*--------*/
  613. sprite_tpl_ops:
  614. sprite_tpl_op
  615. | sprite_tpl_ops sprite_tpl_op
  616. ;
  617. sprite_tpl_op:
  618. KW_TEXNR '(' STRING ')'
  619. { printf ("TEXNR ('%s')\n", $3); }
  620. | KW_FRAME name '(' sprite_verts ')'
  621. { printf ("FRAME '%s' (...)\n", $2); }
  622. | KW_ACTION name '(' sprite_actions ')'
  623. { printf ("ACTION '%s' ( ... )\n", $2); }
  624. | KW_TRIANGLE '(' NUMBER NUMBER NUMBER ')'
  625. { printf ("TRIANGLE (%g,%g,%g)\n", $3, $4, $5); }
  626. | KW_FILE '(' STRING ')'
  627. { printf ("FILE ('%s')\n", $3); }
  628. /*
  629. @@todo:
  630. | <sprite-skeleton>
  631. */
  632. ;
  633. sprite_verts:
  634. /* empty */
  635. | sprite_verts sprite_vert
  636. ;
  637. sprite_vert:
  638. KW_V '(' vector ':' vector2 ')'
  639. { printf ("V (%g,%g,%g:%g,%g)\n", $3.x, $3.y, $3.z, $5.x, $5.y); }
  640. ;
  641. sprite_actions:
  642. /* empty */
  643. | sprite_actions sprite_action
  644. ;
  645. sprite_action:
  646. KW_F '(' STRING ',' NUMBER ')'
  647. { printf ("F ('%s', %g)\n", $3, $5); }
  648. ;
  649. sprite_ops:
  650. sprite_op
  651. | sprite_ops sprite_op
  652. ;
  653. sprite_op:
  654. KW_MOVE '(' move ')'
  655. { printf ("MOVE ()\n"); }
  656. | KW_TEMPLATE '(' STRING ',' STRING ')'
  657. { printf ("TEMPLATE ('%s', '%s')\n", $3, $5); }
  658. | KW_TEXNR '(' STRING ')'
  659. { printf ("TEXNR ('%s')\n", $3); }
  660. | KW_MIXMODE '(' mixmode_ops ')'
  661. { printf ("MIXMODE (...)\n"); }
  662. ;
  663. mixmode_ops:
  664. mixmode_op
  665. | mixmode_ops mixmode_op
  666. ;
  667. mixmode_op:
  668. KW_COPY noargs
  669. | KW_MULTIPLY noargs
  670. | KW_MULTIPLY2 noargs
  671. | KW_ADD noargs
  672. | KW_ALPHA '(' NUMBER ')'
  673. { printf ("ALPHA (%g)\n", $3); }
  674. | KW_TRANSPARENT noargs
  675. | KW_KEYCOLOR noargs
  676. ;
  677. /*--------*/
  678. camera_ops:
  679. /* empty */
  680. | camera_ops camera_op
  681. ;
  682. camera_op:
  683. KW_POSITION '(' vector ')'
  684. { CAMERA.pos.Set ($3); }
  685. | KW_FORWARD '(' vector ')'
  686. { CAMERA.forward.Set ($3); }
  687. | KW_UPWARD '(' vector ')'
  688. { CAMERA.upward.Set ($3); }
  689. | KW_SECTOR '(' STRING ')'
  690. { CAMERA.sector = $3; }
  691. ;
  692. /*-- General-use non-terminals -----------------------------------------------*/
  693. /*
  694. GENERAL NOTE: To minimize space occupied by pre-tokenized data,
  695. the ',' characters between numbers are removed. Thus the lists of
  696. numbers will look like "NUMBER NUMBER NUMBER" instead of (how it
  697. should be in the most obvious case) "NUMBER ',' NUMBER ',' NUMBER".
  698. */
  699. /* A name - either empty or defined */
  700. name:
  701. /* empty == no name */
  702. { $$ = NULL; }
  703. | STRING
  704. ;
  705. /* Yes or no - the result is a boolean */
  706. yesno:
  707. KW_yes
  708. { $$ = true; }
  709. | KW_no
  710. { $$ = false; }
  711. ;
  712. /* Yes or no, one argument, possibly no arguments at all */
  713. yesno_onearg:
  714. /* empty - true by default */
  715. { $$ = true; }
  716. | '(' ')'
  717. { $$ = true; }
  718. | '(' yesno ')'
  719. { $$ = $2; }
  720. ;
  721. /* The definition of a color - red, green, blue from 0 to 1 */
  722. color:
  723. NUMBER NUMBER NUMBER
  724. { CSCOLOR ($$).Set ($1, $2, $3); }
  725. ;
  726. /* Simply a vector */
  727. vector:
  728. NUMBER NUMBER NUMBER
  729. { $$.Set ($1, $2, $3); }
  730. ;
  731. /* A vector defined either directly or using a vertex index */
  732. vect_idx:
  733. NUMBER
  734. /*@@todo*/
  735. { $$.x = $$.y = $$.z = 0; }
  736. | vector
  737. ;
  738. /* A 2D vector */
  739. vector2:
  740. NUMBER NUMBER
  741. { $$.Set ($1, $2); }
  742. ;
  743. /* A matrix: there are lots of ways to define a matrix */
  744. matrix:
  745. NUMBER NUMBER NUMBER
  746. NUMBER NUMBER NUMBER
  747. NUMBER NUMBER NUMBER /* Matrix defined by nine numbers */
  748. {
  749. $$ = &storage.matrix2;
  750. $$->Set ($1, $2, $3, $4, $5, $6, $7, $8, $9);
  751. }
  752. | NUMBER /* Uniform matrix scaler */
  753. {
  754. $$ = &storage.matrix2;
  755. $$->Set ($1, 0, 0, 0, $1, 0, 0, 0, $1);
  756. }
  757. | /* Initialize matrix to identity before starting any complex defs */
  758. {
  759. $$ = &storage.matrix2;
  760. $$->Identity ();
  761. }
  762. matrix_ops
  763. ;
  764. matrix_ops:
  765. matrix_op
  766. | matrix_ops matrix_op
  767. ;
  768. matrix_op:
  769. KW_IDENTITY noargs /* Load identity matrix */
  770. { storage.matrix2.Identity (); }
  771. | KW_ROT_X '(' NUMBER ')' /* Rotate around OX */
  772. { storage.matrix2 *= csXRotMatrix3 ($3); }
  773. | KW_ROT_Y '(' NUMBER ')' /* Rotate around OY */
  774. { storage.matrix2 *= csYRotMatrix3 ($3); }
  775. | KW_ROT_Z '(' NUMBER ')' /* Rotate around OZ */
  776. { storage.matrix2 *= csZRotMatrix3 ($3); }
  777. | KW_SCALE '(' NUMBER ')' /* Uniform matrix scaler */
  778. { storage.matrix2 *= $3; }
  779. | KW_SCALE '(' NUMBER NUMBER NUMBER ')' /* Scalers for X/Y/Z individually */
  780. { storage.matrix2 *= csMatrix3 ($3, 0, 0, 0, $4, 0, 0, 0, $5); }
  781. | KW_SCALE_X '(' NUMBER ')' /* Scale related to YOZ */
  782. { storage.matrix2 *= csXScaleMatrix3 ($3); }
  783. | KW_SCALE_Y '(' NUMBER ')' /* Scale related to XOZ */
  784. { storage.matrix2 *= csYScaleMatrix3 ($3); }
  785. | KW_SCALE_Z '(' NUMBER ')' /* Scale related to XOY */
  786. { storage.matrix2 *= csYScaleMatrix3 ($3); }
  787. ;
  788. noargs:
  789. /* No arguments */
  790. | '(' ')'
  791. ;
  792. /* MOVE ( ... ) operator (used in things/sprites/etc) */
  793. move:
  794. {
  795. $$ = &storage;
  796. $$->matrix.Identity ();
  797. $$->matrix_valid = false;
  798. $$->vector_valid = false;
  799. }
  800. move_ops
  801. ;
  802. move_ops:
  803. move_op
  804. | move_ops move_op
  805. ;
  806. move_op:
  807. KW_MATRIX '(' matrix ')'
  808. {
  809. storage.matrix = *$3;
  810. storage.matrix_valid = true;
  811. }
  812. | KW_V '(' vector ')'
  813. {
  814. storage.vector = CSVECTOR3 ($3);
  815. storage.vector_valid = true;
  816. }
  817. ;
  818. /* POLYGON 'name' ( ... ) (used in things and sectors) */
  819. polygon_ops:
  820. polygon_op
  821. | polygon_ops polygon_op
  822. ;
  823. polygon_op:
  824. KW_TEXNR '(' STRING ')'
  825. { polygon.texname = $3; }
  826. | KW_LIGHTING yesno_onearg
  827. { polygon.object->SetFlags (CS_POLY_LIGHTING, $2 ? CS_POLY_LIGHTING : 0); }
  828. | KW_TEXMAP '('
  829. {
  830. polygon.mode = pmNONE;
  831. polygon.first_len = polygon.second_len = polygon.texlen;
  832. }
  833. polygon_texture_ops ')'
  834. {
  835. if (!CreateTexturePlane (polygon.object))
  836. YYABORT;
  837. }
  838. | KW_VERTICES '(' polygon_vertex_indices ')'
  839. | KW_GOURAUD yesno_onearg
  840. { polygon.object->SetLightingMode ($2); }
  841. | KW_FLATCOL '(' color ')'
  842. { polygon.object->SetFlatColor (CSCOLOR ($3)); }
  843. | KW_ALPHA '(' NUMBER ')'
  844. { polygon.object->SetAlpha ($3); }
  845. | KW_UV '(' tex_coordinates ')'
  846. { printf ("UV (...)\n"); }
  847. | KW_UVA '(' uva_coordinates ')'
  848. { printf ("UVA (...)\n"); }
  849. | KW_COLORS '(' colors ')'
  850. { printf ("COLORS (...)\n"); }
  851. | KW_PORTAL '('
  852. { portals->Push (polygon.portal = new csPPortal (polygon.object)); }
  853. portal_ops ')'
  854. {
  855. if (!polygon.portal->Check ())
  856. {
  857. yyerror ("invalid portal definition");
  858. YYABORT;
  859. }
  860. }
  861. ;
  862. colors:
  863. /* none */
  864. | colors color
  865. { }
  866. ;
  867. polygon_vertex_indices:
  868. /* none */
  869. | polygon_vertex_indices NUMBER
  870. { polygon.object->CreateVertex ($2); }
  871. ;
  872. tex_coordinates:
  873. /* none */
  874. | tex_coordinates NUMBER NUMBER
  875. /* <u> <v> */
  876. ;
  877. uva_coordinates:
  878. /* none */
  879. | uva_coordinates NUMBER NUMBER NUMBER
  880. /* <angle> <uva-scale> <uva-offset> */
  881. ;
  882. /* PORTAL ( ... ) */
  883. portal_ops:
  884. portal_op
  885. | portal_ops portal_op
  886. ;
  887. portal_op:
  888. KW_SECTOR '(' STRING ')'
  889. { polygon.portal->destsec = $3; }
  890. | KW_MATRIX '(' matrix ')'
  891. { polygon.portal->mode = csPPortal::pmWarp; }
  892. | KW_V '(' vector ')'
  893. { polygon.portal->mode = csPPortal::pmWarp; }
  894. | KW_W '(' vector ')'
  895. { polygon.portal->mode = csPPortal::pmWarp; }
  896. | KW_MIRROR yesno_onearg
  897. { polygon.portal->mode = csPPortal::pmMirror; }
  898. | KW_STATIC yesno_onearg
  899. { polygon.portal->SetFlags (CS_PORTAL_STATICDEST, $2); }
  900. | KW_CLIP yesno_onearg
  901. { polygon.portal->SetFlags (CS_PORTAL_CLIPDEST, $2); }
  902. | KW_ZFILL yesno_onearg
  903. { polygon.portal->SetFlags (CS_PORTAL_ZFILL, $2); }
  904. ;
  905. /* TEXTURE (...) */
  906. polygon_texture_ops:
  907. polygon_texture_op
  908. | polygon_texture_ops polygon_texture_op
  909. ;
  910. polygon_texture_op:
  911. KW_ORIG '(' vect_idx ')'
  912. {
  913. polygon.mode |= pmORIGIN;
  914. polygon.origin.Set ($3);
  915. }
  916. | KW_FIRST '(' vect_idx ')'
  917. {
  918. polygon.mode |= pmFIRSTSECOND;
  919. polygon.first.Set ($3);
  920. }
  921. | KW_SECOND '(' vect_idx ')'
  922. {
  923. polygon.mode |= pmFIRSTSECOND;
  924. polygon.second.Set ($3);
  925. }
  926. | KW_FIRST_LEN '(' NUMBER ')'
  927. {
  928. polygon.mode |= pmFIRSTSECOND;
  929. polygon.first_len = $3;
  930. }
  931. | KW_SECOND_LEN '(' NUMBER ')'
  932. {
  933. polygon.mode |= pmFIRSTSECOND;
  934. polygon.second_len = $3;
  935. }
  936. | KW_UVEC '(' vector ')'
  937. {
  938. polygon.mode |= pmVECTORS;
  939. polygon.first = $3;
  940. polygon.first_len = 1.0;
  941. }
  942. | KW_VVEC '(' vector ')'
  943. {
  944. polygon.mode |= pmVECTORS;
  945. polygon.second = $3;
  946. polygon.second_len = 1.0;
  947. }
  948. | KW_MATRIX '(' matrix ')'
  949. {
  950. polygon.mode |= pmMATRIX;
  951. polygon.matrix.Set (*$3);
  952. }
  953. | KW_V '(' vector ')'
  954. {
  955. polygon.mode |= pmMATRIX;
  956. polygon.origin.Set ($3);
  957. }
  958. | KW_PLANE '(' STRING ')'
  959. {
  960. polygon.mode |= pmPLANEREF;
  961. polygon.planetpl = $3;
  962. }
  963. | KW_UV_SHIFT '(' vector2 ')'
  964. { printf ("UV_SHIFT (%g, %g)\n", $3.x, $3.y); }
  965. ;
  966. %% /* End of grammar */
  967. /* On initialization, register keyword list with the C++ parser */
  968. extern int init_token_table (const char * const *yytname);
  969. struct __parser_init
  970. {
  971. __parser_init ()
  972. {
  973. init_token_table (yytname);
  974. #if YYDEBUG
  975. yydebug = 1;
  976. #endif
  977. }
  978. } __parser_init_dummy;