From 215d27185092f5a72faf3bfdcf843ece0d985992 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Tue, 24 Nov 2009 01:24:10 -0500 Subject: Rename flex and bison input files. --- .gitignore | 6 +- dimension/Makefile.am | 6 +- dimension/bison.y | 1119 ------------------------------------------------- dimension/flex.l | 291 ------------- dimension/grammar.y | 1119 +++++++++++++++++++++++++++++++++++++++++++++++++ dimension/lexer.l | 291 +++++++++++++ dimension/tokenize.h | 2 +- 7 files changed, 1417 insertions(+), 1417 deletions(-) delete mode 100644 dimension/bison.y delete mode 100644 dimension/flex.l create mode 100644 dimension/grammar.y create mode 100644 dimension/lexer.l diff --git a/.gitignore b/.gitignore index e373695..9f28a67 100644 --- a/.gitignore +++ b/.gitignore @@ -40,9 +40,9 @@ Makefile.in # Files created by `make' /dimension/dimension -/dimension/bison.c -/dimension/bison.h -/dimension/flex.c +/dimension/grammar.c +/dimension/grammar.h +/dimension/lexer.c # Files created by `make check' /tests/*/*-test diff --git a/dimension/Makefile.am b/dimension/Makefile.am index 7d2e11a..4b7d20b 100644 --- a/dimension/Makefile.am +++ b/dimension/Makefile.am @@ -22,10 +22,10 @@ INCLUDES = -I$(top_srcdir)/libdimension bin_PROGRAMS = dimension AM_YFLAGS = -d -BUILT_SOURCES = bison.h +BUILT_SOURCES = grammar.h -dimension_SOURCES = bison.y \ - flex.l \ +dimension_SOURCES = grammar.y \ + lexer.l \ main.c \ parse.h \ progressbar.c \ diff --git a/dimension/bison.y b/dimension/bison.y deleted file mode 100644 index 426bc29..0000000 --- a/dimension/bison.y +++ /dev/null @@ -1,1119 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009 Tavian Barnes * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -%{ -#include "parse.h" -#include "tokenize.h" -#include "utility.h" -#include -#include - -typedef struct dmnsn_token_iterator { - const dmnsn_array *tokens; - unsigned int i; -} dmnsn_token_iterator; - -typedef struct dmnsn_location { - const char *first_filename, *last_filename; - int first_line, last_line; - int first_column, last_column; -} dmnsn_location; - -typedef union YYSTYPE { - const char *value; - dmnsn_astnode astnode; -} YYSTYPE; - -#define YYLTYPE dmnsn_location -#define YYLLOC_DEFAULT(Current, Rhs, N) \ - do { \ - if (N) { \ - (Current).first_filename = YYRHSLOC(Rhs, 1).first_filename; \ - (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \ - (Current).last_filename = YYRHSLOC(Rhs, N).last_filename; \ - (Current).last_line = YYRHSLOC(Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC(Rhs, N).last_column; \ - } else { \ - (Current).first_filename = (Current).last_filename = \ - YYRHSLOC(Rhs, 0).last_filename; \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC(Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC(Rhs, 0).last_column; \ - } \ - } while (0) - -/* Create a new astnode, populating filename, line, and col */ - -static dmnsn_astnode -dmnsn_copy_astnode(dmnsn_astnode astnode) -{ - dmnsn_astnode copy = { - .type = astnode.type, - .children = dmnsn_new_array(sizeof(dmnsn_astnode)), - .ptr = NULL, - .filename = astnode.filename, - .line = astnode.line, - .col = astnode.col - }; - return copy; -} - -static dmnsn_astnode -dmnsn_new_astnode(dmnsn_astnode_type type, YYLTYPE lloc) -{ - dmnsn_astnode astnode = { - .type = type, - .children = dmnsn_new_array(sizeof(dmnsn_astnode)), - .ptr = NULL, - .filename = lloc.first_filename, - .line = lloc.first_line, - .col = lloc.first_column - }; - return astnode; -} - -static dmnsn_astnode -dmnsn_new_astnode1(dmnsn_astnode_type type, YYLTYPE lloc, dmnsn_astnode n1) -{ - dmnsn_astnode astnode = dmnsn_new_astnode(type, lloc); - dmnsn_array_push(astnode.children, &n1); - return astnode; -} - -static dmnsn_astnode -dmnsn_new_astnode2(dmnsn_astnode_type type, YYLTYPE lloc, - dmnsn_astnode n1, dmnsn_astnode n2) -{ - dmnsn_astnode astnode = dmnsn_new_astnode(type, lloc); - dmnsn_array_push(astnode.children, &n1); - dmnsn_array_push(astnode.children, &n2); - return astnode; -} - -static dmnsn_astnode -dmnsn_new_astnode3(dmnsn_astnode_type type, YYLTYPE lloc, - dmnsn_astnode n1, dmnsn_astnode n2, dmnsn_astnode n3) -{ - dmnsn_astnode astnode = dmnsn_new_astnode(type, lloc); - dmnsn_array_push(astnode.children, &n1); - dmnsn_array_push(astnode.children, &n2); - dmnsn_array_push(astnode.children, &n3); - return astnode; -} - -/* Delete a single, unused astnode */ -static void -dmnsn_delete_astnode(dmnsn_astnode astnode) -{ - dmnsn_delete_astree(astnode.children); - free(astnode.ptr); -} - -static int -yylex(YYSTYPE *lvalp, YYLTYPE *llocp, dmnsn_token_iterator *iterator) -{ - if (iterator->i >= dmnsn_array_size(iterator->tokens)) { - return 0; - } else { - dmnsn_token token; - dmnsn_array_get(iterator->tokens, iterator->i, &token); - ++iterator->i; - - lvalp->value = token.value; - - llocp->first_filename = llocp->last_filename = token.filename; - llocp->first_line = llocp->last_line = token.line; - llocp->first_column = llocp->last_column = token.col; - - return token.type; - } -} - -void -yyerror(YYLTYPE *locp, dmnsn_array *astree, dmnsn_token_iterator *iterator, - const char *str) -{ - dmnsn_diagnostic(locp->first_filename, locp->first_line, locp->first_column, - "%s", str); -} -%} - -%define api.pure -%locations -%error-verbose -%token-table - -%parse-param {dmnsn_array *astree} -%parse-param {dmnsn_token_iterator *iterator} -%lex-param {dmnsn_token_iterator *iterator} - -%token END 0 "end-of-file" - -/* Punctuation */ -%token DMNSN_T_LBRACE "{" -%token DMNSN_T_RBRACE "}" -%token DMNSN_T_LPAREN "(" -%token DMNSN_T_RPAREN ")" -%token DMNSN_T_LBRACKET "[" -%token DMNSN_T_RBRACKET "]" -%token DMNSN_T_PLUS "+" -%token DMNSN_T_MINUS "-" -%token DMNSN_T_STAR "*" -%token DMNSN_T_SLASH "/" -%token DMNSN_T_COMMA "," -%token DMNSN_T_SEMICOLON ";" -%token DMNSN_T_QUESTION "?" -%token DMNSN_T_COLON ":" -%token DMNSN_T_AND "&" -%token DMNSN_T_DOT "." -%token DMNSN_T_PIPE "|" -%token DMNSN_T_LESS "<" -%token DMNSN_T_GREATER ">" -%token DMNSN_T_BANG "!" -%token DMNSN_T_EQUALS "=" -%token DMNSN_T_LESS_EQUAL "<=" -%token DMNSN_T_GREATER_EQUAL ">=" -%token DMNSN_T_NOT_EQUAL "!=" - -/* Numeric values */ -%token DMNSN_T_INTEGER "integer" -%token DMNSN_T_FLOAT "float" - -/* Keywords */ -%token DMNSN_T_AA_LEVEL -%token DMNSN_T_AA_THRESHOLD -%token DMNSN_T_ABS -%token DMNSN_T_ABSORPTION -%token DMNSN_T_ACCURACY -%token DMNSN_T_ACOS -%token DMNSN_T_ACOSH -%token DMNSN_T_ADAPTIVE -%token DMNSN_T_ADC_BAILOUT -%token DMNSN_T_AGATE -%token DMNSN_T_AGATE_TURB -%token DMNSN_T_ALL -%token DMNSN_T_ALL_INTERSECTIONS -%token DMNSN_T_ALPHA -%token DMNSN_T_ALTITUDE -%token DMNSN_T_ALWAYS_SAMPLE -%token DMNSN_T_AMBIENT -%token DMNSN_T_AMBIENT_LIGHT -%token DMNSN_T_ANGLE -%token DMNSN_T_APERTURE -%token DMNSN_T_APPEND -%token DMNSN_T_ARC_ANGLE -%token DMNSN_T_AREA_LIGHT -%token DMNSN_T_ARRAY -%token DMNSN_T_ASC -%token DMNSN_T_ASCII -%token DMNSN_T_ASIN -%token DMNSN_T_ASINH -%token DMNSN_T_ASSUMED_GAMMA -%token DMNSN_T_ATAN -%token DMNSN_T_ATAN2 -%token DMNSN_T_ATANH -%token DMNSN_T_AUTOSTOP -%token DMNSN_T_AVERAGE -%token DMNSN_T_B_SPLINE -%token DMNSN_T_BACKGROUND -%token DMNSN_T_BEZIER_SPLINE -%token DMNSN_T_BICUBIC_PATCH -%token DMNSN_T_BLACK_HOLE -%token DMNSN_T_BLOB -%token DMNSN_T_BLUE -%token DMNSN_T_BLUR_SAMPLES -%token DMNSN_T_BOUNDED_BY -%token DMNSN_T_BOX "box" -%token DMNSN_T_BOXED -%token DMNSN_T_BOZO -%token DMNSN_T_BRICK -%token DMNSN_T_BRICK_SIZE -%token DMNSN_T_BRIGHTNESS -%token DMNSN_T_BRILLIANCE -%token DMNSN_T_BUMP_MAP -%token DMNSN_T_BUMP_SIZE -%token DMNSN_T_BUMPS -%token DMNSN_T_CAMERA "camera" -%token DMNSN_T_CAUSTICS -%token DMNSN_T_CEIL -%token DMNSN_T_CELLS -%token DMNSN_T_CHARSET -%token DMNSN_T_CHECKER -%token DMNSN_T_CHR -%token DMNSN_T_CIRCULAR -%token DMNSN_T_CLIPPED_BY -%token DMNSN_T_CLOCK -%token DMNSN_T_CLOCK_DELTA -%token DMNSN_T_CLOCK_ON -%token DMNSN_T_COLLECT -%token DMNSN_T_COLOR "color" -%token DMNSN_T_COLOR_MAP -%token DMNSN_T_COMPONENT -%token DMNSN_T_COMPOSITE -%token DMNSN_T_CONCAT -%token DMNSN_T_CONE -%token DMNSN_T_CONFIDENCE -%token DMNSN_T_CONIC_SWEEP -%token DMNSN_T_CONSERVE_ENERGY -%token DMNSN_T_CONTAINED_BY -%token DMNSN_T_CONTROL0 -%token DMNSN_T_CONTROL1 -%token DMNSN_T_COORDS -%token DMNSN_T_COS -%token DMNSN_T_COSH -%token DMNSN_T_COUNT -%token DMNSN_T_CRACKLE -%token DMNSN_T_CRAND -%token DMNSN_T_CUBE -%token DMNSN_T_CUBIC -%token DMNSN_T_CUBIC_SPLINE -%token DMNSN_T_CUBIC_WAVE -%token DMNSN_T_CUTAWAY_TEXTURES -%token DMNSN_T_CYLINDER -%token DMNSN_T_CYLINDRICAL -%token DMNSN_T_DEFINED -%token DMNSN_T_DEGREES -%token DMNSN_T_DENSITY -%token DMNSN_T_DENSITY_FILE -%token DMNSN_T_DENSITY_MAP -%token DMNSN_T_DENTS -%token DMNSN_T_DF3 -%token DMNSN_T_DIFFERENCE -%token DMNSN_T_DIFFUSE -%token DMNSN_T_DIMENSION_SIZE -%token DMNSN_T_DIMENSIONS -%token DMNSN_T_DIRECTION -%token DMNSN_T_DISC -%token DMNSN_T_DISPERSION -%token DMNSN_T_DISPERSION_SAMPLES -%token DMNSN_T_DIST_EXP -%token DMNSN_T_DISTANCE -%token DMNSN_T_DIV -%token DMNSN_T_DOUBLE_ILLUMINATE -%token DMNSN_T_ECCENTRICITY -%token DMNSN_T_EMISSION -%token DMNSN_T_ERROR_BOUND -%token DMNSN_T_EVALUATE -%token DMNSN_T_EXP -%token DMNSN_T_EXPAND_THRESHOLDS -%token DMNSN_T_EXPONENT -%token DMNSN_T_EXTERIOR -%token DMNSN_T_EXTINCTION -%token DMNSN_T_FACE_INDICES -%token DMNSN_T_FACETS -%token DMNSN_T_FADE_COLOR -%token DMNSN_T_FADE_DISTANCE -%token DMNSN_T_FADE_POWER -%token DMNSN_T_FALLOFF -%token DMNSN_T_FALLOFF_ANGLE -%token DMNSN_T_FALSE -%token DMNSN_T_FILE_EXISTS -%token DMNSN_T_FILTER -%token DMNSN_T_FINAL_CLOCK -%token DMNSN_T_FINAL_FRAME -%token DMNSN_T_FINISH -%token DMNSN_T_FISHEYE -%token DMNSN_T_FLATNESS -%token DMNSN_T_FLIP -%token DMNSN_T_FLOOR -%token DMNSN_T_FOCAL_POINT -%token DMNSN_T_FOG -%token DMNSN_T_FOG_ALT -%token DMNSN_T_FOG_OFFSET -%token DMNSN_T_FOG_TYPE -%token DMNSN_T_FORM -%token DMNSN_T_FRAME_NUMBER -%token DMNSN_T_FREQUENCY -%token DMNSN_T_FRESNEL -%token DMNSN_T_FUNCTION -%token DMNSN_T_GATHER -%token DMNSN_T_GIF -%token DMNSN_T_GLOBAL_LIGHTS -%token DMNSN_T_GLOBAL_SETTINGS -%token DMNSN_T_GRADIENT -%token DMNSN_T_GRANITE -%token DMNSN_T_GRAY -%token DMNSN_T_GRAY_THRESHOLD -%token DMNSN_T_GREEN -%token DMNSN_T_HEIGHT_FIELD -%token DMNSN_T_HEXAGON -%token DMNSN_T_HF_GRAY_16 -%token DMNSN_T_HIERARCHY -%token DMNSN_T_HYPERCOMPLEX -%token DMNSN_T_HOLLOW -%token DMNSN_T_IFF -%token DMNSN_T_IMAGE_HEIGHT -%token DMNSN_T_IMAGE_MAP -%token DMNSN_T_IMAGE_PATTERN -%token DMNSN_T_IMAGE_WIDTH -%token DMNSN_T_INITIAL_CLOCK -%token DMNSN_T_INITIAL_FRAME -%token DMNSN_T_INSIDE -%token DMNSN_T_INSIDE_VECTOR -%token DMNSN_T_INT -%token DMNSN_T_INTERIOR -%token DMNSN_T_INTERIOR_TEXTURE -%token DMNSN_T_INTERNAL -%token DMNSN_T_INTERPOLATE -%token DMNSN_T_INTERSECTION -%token DMNSN_T_INTERVALS -%token DMNSN_T_INVERSE -%token DMNSN_T_IOR -%token DMNSN_T_IRID -%token DMNSN_T_IRID_WAVELENGTH -%token DMNSN_T_ISOSURFACE -%token DMNSN_T_JITTER -%token DMNSN_T_JPEG -%token DMNSN_T_JULIA -%token DMNSN_T_JULIA_FRACTAL -%token DMNSN_T_LAMBDA -%token DMNSN_T_LATHE -%token DMNSN_T_LEOPARD -%token DMNSN_T_LIGHT_GROUP -%token DMNSN_T_LIGHT_SOURCE -%token DMNSN_T_LINEAR_SPLINE -%token DMNSN_T_LINEAR_SWEEP -%token DMNSN_T_LN -%token DMNSN_T_LOAD_FILE -%token DMNSN_T_LOCATION -%token DMNSN_T_LOG -%token DMNSN_T_LOOK_AT -%token DMNSN_T_LOOKS_LIKE -%token DMNSN_T_LOW_ERROR_FACTOR -%token DMNSN_T_MAGNET -%token DMNSN_T_MAJOR_RADIUS -%token DMNSN_T_MANDEL -%token DMNSN_T_MAP_TYPE -%token DMNSN_T_MARBLE -%token DMNSN_T_MATERIAL -%token DMNSN_T_MATERIAL_MAP -%token DMNSN_T_MATRIX -%token DMNSN_T_MAX -%token DMNSN_T_MAX_EXTENT -%token DMNSN_T_MAX_GRADIENT -%token DMNSN_T_MAX_INTERSECTIONS -%token DMNSN_T_MAX_ITERATION -%token DMNSN_T_MAX_SAMPLE -%token DMNSN_T_MAX_TRACE -%token DMNSN_T_MAX_TRACE_LEVEL -%token DMNSN_T_MEDIA -%token DMNSN_T_MEDIA_ATTENUATION -%token DMNSN_T_MEDIA_INTERACTION -%token DMNSN_T_MERGE -%token DMNSN_T_MESH -%token DMNSN_T_MESH2 -%token DMNSN_T_METALLIC -%token DMNSN_T_METHOD -%token DMNSN_T_METRIC -%token DMNSN_T_MIN -%token DMNSN_T_MIN_EXTENT -%token DMNSN_T_MINIMUM_REUSE -%token DMNSN_T_MOD -%token DMNSN_T_MORTAR -%token DMNSN_T_NATURAL_SPLINE -%token DMNSN_T_NEAREST_COUNT -%token DMNSN_T_NO -%token DMNSN_T_NO_BUMP_SCALE -%token DMNSN_T_NO_IMAGE -%token DMNSN_T_NO_REFLECTION -%token DMNSN_T_NO_SHADOW -%token DMNSN_T_NOISE_GENERATOR -%token DMNSN_T_NORMAL -%token DMNSN_T_NORMAL_INDICES -%token DMNSN_T_NORMAL_MAP -%token DMNSN_T_NORMAL_VECTORS -%token DMNSN_T_NUMBER_OF_WAVES -%token DMNSN_T_OBJECT -%token DMNSN_T_OCTAVES -%token DMNSN_T_OFF -%token DMNSN_T_OFFSET -%token DMNSN_T_OMEGA -%token DMNSN_T_OMNIMAX -%token DMNSN_T_ON -%token DMNSN_T_ONCE -%token DMNSN_T_ONION -%token DMNSN_T_OPEN -%token DMNSN_T_ORIENT -%token DMNSN_T_ORIENTATION -%token DMNSN_T_ORTHOGRAPHIC -%token DMNSN_T_PANORAMIC -%token DMNSN_T_PARALLEL -%token DMNSN_T_PARAMETRIC -%token DMNSN_T_PASS_THROUGH -%token DMNSN_T_PATTERN -%token DMNSN_T_PERSPECTIVE -%token DMNSN_T_PGM -%token DMNSN_T_PHASE -%token DMNSN_T_PHONG -%token DMNSN_T_PHONG_SIZE -%token DMNSN_T_PHOTONS -%token DMNSN_T_PI -%token DMNSN_T_PIGMENT -%token DMNSN_T_PIGMENT_MAP -%token DMNSN_T_PIGMENT_PATTERN -%token DMNSN_T_PLANAR -%token DMNSN_T_PLANE -%token DMNSN_T_PNG -%token DMNSN_T_POINT_AT -%token DMNSN_T_POLY -%token DMNSN_T_POLY_WAVE -%token DMNSN_T_POLYGON -%token DMNSN_T_POT -%token DMNSN_T_POW -%token DMNSN_T_PPM -%token DMNSN_T_PRECISION -%token DMNSN_T_PRECOMPUTE -%token DMNSN_T_PRETRACE_END -%token DMNSN_T_PRETRACE_START -%token DMNSN_T_PRISM -%token DMNSN_T_PROD -%token DMNSN_T_PROJECTED_THROUGH -%token DMNSN_T_PWR -%token DMNSN_T_QUADRATIC_SPLINE -%token DMNSN_T_QUADRIC -%token DMNSN_T_QUARTIC -%token DMNSN_T_QUATERNION -%token DMNSN_T_QUICK_COLOR -%token DMNSN_T_QUILTED -%token DMNSN_T_RADIAL -%token DMNSN_T_RADIANS -%token DMNSN_T_RADIOSITY -%token DMNSN_T_RADIUS -%token DMNSN_T_RAINBOW -%token DMNSN_T_RAMP_WAVE -%token DMNSN_T_RAND -%token DMNSN_T_RATIO -%token DMNSN_T_RECIPROCAL -%token DMNSN_T_RECURSION_LIMIT -%token DMNSN_T_RED -%token DMNSN_T_REFLECTION -%token DMNSN_T_REFLECTION_EXPONENT -%token DMNSN_T_REFRACTION -%token DMNSN_T_REPEAT -%token DMNSN_T_RGB -%token DMNSN_T_RGBF -%token DMNSN_T_RGBFT -%token DMNSN_T_RGBT -%token DMNSN_T_RIGHT -%token DMNSN_T_RIPPLES -%token DMNSN_T_ROTATE -%token DMNSN_T_ROUGHNESS -%token DMNSN_T_SAMPLES -%token DMNSN_T_SAVE_FILE -%token DMNSN_T_SCALE -%token DMNSN_T_SCALLOP_WAVE -%token DMNSN_T_SCATTERING -%token DMNSN_T_SEED -%token DMNSN_T_SELECT -%token DMNSN_T_SHADOWLESS -%token DMNSN_T_SIN -%token DMNSN_T_SINE_WAVE -%token DMNSN_T_SINH -%token DMNSN_T_SIZE -%token DMNSN_T_SKY -%token DMNSN_T_SKY_SPHERE -%token DMNSN_T_SLICE -%token DMNSN_T_SLOPE -%token DMNSN_T_SLOPE_MAP -%token DMNSN_T_SMOOTH -%token DMNSN_T_SMOOTH_TRIANGLE -%token DMNSN_T_SOLID -%token DMNSN_T_SOR -%token DMNSN_T_SPACING -%token DMNSN_T_SPECULAR -%token DMNSN_T_SPHERE "sphere" -%token DMNSN_T_SPHERE_SWEEP -%token DMNSN_T_SPHERICAL -%token DMNSN_T_SPIRAL1 -%token DMNSN_T_SPIRAL2 -%token DMNSN_T_SPLINE -%token DMNSN_T_SPLIT_UNION -%token DMNSN_T_SPOTLIGHT -%token DMNSN_T_SPOTTED -%token DMNSN_T_SQR -%token DMNSN_T_SQRT -%token DMNSN_T_STR -%token DMNSN_T_STRCMP -%token DMNSN_T_STRENGTH -%token DMNSN_T_STRLEN -%token DMNSN_T_STRLWR -%token DMNSN_T_STRUPR -%token DMNSN_T_STURM -%token DMNSN_T_SUBSTR -%token DMNSN_T_SUM -%token DMNSN_T_SUPERELLIPSOID -%token DMNSN_T_SYS -%token DMNSN_T_T -%token DMNSN_T_TAN -%token DMNSN_T_TANH -%token DMNSN_T_TARGET -%token DMNSN_T_TEXT -%token DMNSN_T_TEXTURE -%token DMNSN_T_TEXTURE_LIST -%token DMNSN_T_TEXTURE_MAP -%token DMNSN_T_TGA -%token DMNSN_T_THICKNESS -%token DMNSN_T_THRESHOLD -%token DMNSN_T_TIFF -%token DMNSN_T_TIGHTNESS -%token DMNSN_T_TILE2 -%token DMNSN_T_TILES -%token DMNSN_T_TOLERANCE -%token DMNSN_T_TOROIDAL -%token DMNSN_T_TORUS -%token DMNSN_T_TRACE -%token DMNSN_T_TRANSFORM -%token DMNSN_T_TRANSLATE -%token DMNSN_T_TRANSMIT -%token DMNSN_T_TRIANGLE -%token DMNSN_T_TRIANGLE_WAVE -%token DMNSN_T_TRUE -%token DMNSN_T_TTF -%token DMNSN_T_TURB_DEPTH -%token DMNSN_T_TURBULENCE -%token DMNSN_T_TYPE -%token DMNSN_T_U -%token DMNSN_T_U_STEPS -%token DMNSN_T_ULTRA_WIDE_ANGLE -%token DMNSN_T_UNION -%token DMNSN_T_UP -%token DMNSN_T_USE_ALPHA -%token DMNSN_T_USE_COLOR -%token DMNSN_T_USE_INDEX -%token DMNSN_T_UTF8 -%token DMNSN_T_UV_INDICES -%token DMNSN_T_UV_MAPPING -%token DMNSN_T_UV_VECTORS -%token DMNSN_T_V -%token DMNSN_T_V_STEPS -%token DMNSN_T_VAL -%token DMNSN_T_VARIANCE -%token DMNSN_T_VAXIS_ROTATE -%token DMNSN_T_VCROSS -%token DMNSN_T_VDOT -%token DMNSN_T_VERTEX_VECTORS -%token DMNSN_T_VLENGTH -%token DMNSN_T_VNORMALIZE -%token DMNSN_T_VROTATE -%token DMNSN_T_VSTR -%token DMNSN_T_VTURBULENCE -%token DMNSN_T_WARP -%token DMNSN_T_WATER_LEVEL -%token DMNSN_T_WAVES -%token DMNSN_T_WIDTH -%token DMNSN_T_WOOD -%token DMNSN_T_WRINKLES -%token DMNSN_T_X -%token DMNSN_T_Y -%token DMNSN_T_YES -%token DMNSN_T_Z - -/* Directives (#declare etc.) */ -%token DMNSN_T_BREAK -%token DMNSN_T_CASE -%token DMNSN_T_DEBUG -%token DMNSN_T_DECLARE "#declare" -%token DMNSN_T_DEFAULT -%token DMNSN_T_ELSE -%token DMNSN_T_END -%token DMNSN_T_ERROR -%token DMNSN_T_FCLOSE -%token DMNSN_T_FOPEN -%token DMNSN_T_IF -%token DMNSN_T_IFDEF -%token DMNSN_T_IFNDEF -%token DMNSN_T_INCLUDE "#include" -%token DMNSN_T_LOCAL -%token DMNSN_T_MACRO -%token DMNSN_T_RANGE -%token DMNSN_T_READ -%token DMNSN_T_RENDER -%token DMNSN_T_STATISTICS -%token DMNSN_T_SWITCH -%token DMNSN_T_UNDEF -%token DMNSN_T_VERSION -%token DMNSN_T_WARNING -%token DMNSN_T_WHILE -%token DMNSN_T_WRITE - -/* Identifiers */ -%token DMNSN_T_IDENTIFIER "identifier" - -/* Strings */ -%token DMNSN_T_STRING "string" - -/* Top-level items */ -%type SCENE_ITEM - -/* Objects */ -%type OBJECT -%type FINITE_SOLID_OBJECT -%type BOX -%type SPHERE - -/* Floats */ -%type FLOAT -%type FLOAT_TERM -%type FLOAT_FACTOR -%type FLOAT_LITERAL - -/* Vectors */ -%type VECTOR -%type VECTOR_LITERAL - -%destructor { dmnsn_delete_astnode($$); } - -%% - -SCENE: /* empty */ { } - | SCENE SCENE_ITEM { - dmnsn_array_push(astree, &$2); - } -; - -SCENE_ITEM: OBJECT -; - -OBJECT: FINITE_SOLID_OBJECT -; - -FINITE_SOLID_OBJECT: BOX - | SPHERE -; - -BOX: "box" "{" - VECTOR "," VECTOR - "}" - { - $$ = dmnsn_new_astnode2(DMNSN_AST_BOX, @$, $3, $5); - } -; - -SPHERE: "sphere" "{" - VECTOR "," FLOAT - "}" - { - $$ = dmnsn_new_astnode2(DMNSN_AST_SPHERE, @$, $3, $5); - } -; - -FLOAT: FLOAT_TERM - { - $$ = dmnsn_eval_scalar($1); - dmnsn_delete_astnode($1); - } - | FLOAT "+" FLOAT_TERM - { - dmnsn_astnode sum = dmnsn_new_astnode2(DMNSN_AST_ADD, @$, $1, $3); - $$ = dmnsn_eval_scalar(sum); - dmnsn_delete_astnode(sum); - } - | FLOAT "-" FLOAT_TERM - { - dmnsn_astnode diff = dmnsn_new_astnode2(DMNSN_AST_SUB, @$, $1, $3); - $$ = dmnsn_eval_scalar(diff); - dmnsn_delete_astnode(diff); - } -; - -FLOAT_TERM: FLOAT_FACTOR - | FLOAT_TERM "*" FLOAT_FACTOR - { - $$ = dmnsn_new_astnode2(DMNSN_AST_MUL, @$, $1, $3); - } - | FLOAT_TERM "/" FLOAT_FACTOR - { - $$ = dmnsn_new_astnode2(DMNSN_AST_DIV, @$, $1, $3); - } - -FLOAT_FACTOR: FLOAT_LITERAL - | "+" FLOAT_FACTOR { $$ = $2; } - | "-" FLOAT_FACTOR - { - $$ = dmnsn_new_astnode1(DMNSN_AST_NEGATE, @$, $2); - } - | "(" FLOAT ")" { $$ = $2; } - -FLOAT_LITERAL: "integer" - { - $$ = dmnsn_new_astnode(DMNSN_AST_INTEGER, @$); - $$.ptr = malloc(sizeof(long)); - if (!$$.ptr) - dmnsn_error(DMNSN_SEVERITY_HIGH, - "Failed to allocate room for integer."); - - *(long *)$$.ptr = strtol($1, NULL, 0); - } - | "float" - { - $$ = dmnsn_new_astnode(DMNSN_AST_FLOAT, @$); - $$.ptr = malloc(sizeof(double)); - if (!$$.ptr) - dmnsn_error(DMNSN_SEVERITY_HIGH, - "Failed to allocate room for float."); - - *(double *)$$.ptr = strtod($1, NULL); - } -; - -VECTOR: VECTOR_LITERAL -; - -VECTOR_LITERAL: "<" FLOAT "," FLOAT "," FLOAT ">" - { - $$ = dmnsn_new_astnode3(DMNSN_AST_VECTOR, @$, $2, $4, $6); - } -; - -%% - -dmnsn_array * -dmnsn_parse(const dmnsn_array *tokens) -{ - dmnsn_array *astree = dmnsn_new_array(sizeof(dmnsn_astnode)); - dmnsn_token_iterator iterator = { .tokens = tokens, .i = 0 }; - - if (yyparse(astree, &iterator) != 0) { - dmnsn_delete_astree(astree); - return NULL; - } - - return astree; -} - -void -dmnsn_delete_astree(dmnsn_array *astree) -{ - unsigned int i; - dmnsn_astnode node; - - if (astree) { - for (i = 0; i < dmnsn_array_size(astree); ++i) { - dmnsn_array_get(astree, i, &node); - dmnsn_delete_astree(node.children); - free(node.ptr); - } - dmnsn_delete_array(astree); - } -} - -static dmnsn_astnode -dmnsn_eval_scalar_unary(dmnsn_astnode astnode) -{ - dmnsn_astnode ret = dmnsn_copy_astnode(astnode), rhs; - dmnsn_array_get(astnode.children, 0, &rhs); - rhs = dmnsn_eval_scalar(rhs); - - if (rhs.type == DMNSN_AST_INTEGER) { - long n = *(long *)rhs.ptr; - long *res = malloc(sizeof(long)); - if (!res) - dmnsn_error(DMNSN_SEVERITY_HIGH, "Failed to allocate room for integer."); - - switch(astnode.type) { - case DMNSN_AST_NEGATE: - *res = -n; - break; - - default: - dmnsn_error(DMNSN_SEVERITY_HIGH, - "Attempt to evaluate wrong unary operator."); - } - - ret.type = DMNSN_AST_INTEGER; - ret.ptr = res; - } else if (rhs.type == DMNSN_AST_FLOAT) { - double n = *(double *)rhs.ptr; - double *res = malloc(sizeof(double)); - if (!res) - dmnsn_error(DMNSN_SEVERITY_HIGH, "Failed to allocate room for float."); - - switch(astnode.type) { - case DMNSN_AST_NEGATE: - *res = -n; - break; - - default: - dmnsn_error(DMNSN_SEVERITY_HIGH, - "Attempt to evaluate wrong unary operator."); - } - - ret.type = DMNSN_AST_FLOAT; - ret.ptr = res; - } else { - dmnsn_error(DMNSN_SEVERITY_HIGH, - "Invalid right hand side to unary operator."); - } - - dmnsn_delete_astnode(rhs); - return ret; -} - -static dmnsn_astnode -dmnsn_eval_scalar_binary(dmnsn_astnode astnode) -{ - dmnsn_astnode ret = dmnsn_copy_astnode(astnode), lhs, rhs; - dmnsn_array_get(astnode.children, 0, &lhs); - dmnsn_array_get(astnode.children, 1, &rhs); - lhs = dmnsn_eval_scalar(lhs); - rhs = dmnsn_eval_scalar(rhs); - - if (lhs.type == DMNSN_AST_INTEGER && rhs.type == DMNSN_AST_INTEGER - && astnode.type != DMNSN_AST_DIV) { - long l, r; - l = *(long *)lhs.ptr; - r = *(long *)rhs.ptr; - - long *res = malloc(sizeof(long)); - if (!res) - dmnsn_error(DMNSN_SEVERITY_HIGH, "Failed to allocate room for integer."); - - switch (astnode.type) { - case DMNSN_AST_ADD: - *res = l + r; - break; - case DMNSN_AST_SUB: - *res = l - r; - break; - case DMNSN_AST_MUL: - *res = l*r; - break; - - default: - dmnsn_error(DMNSN_SEVERITY_HIGH, - "Attempt to evaluate wrong binary operator."); - } - - ret.type = DMNSN_AST_INTEGER; - ret.ptr = res; - } else { - double l = 0.0, r = 0.0; - - if (lhs.type == DMNSN_AST_INTEGER) - l = *(long *)lhs.ptr; - else if (lhs.type == DMNSN_AST_FLOAT) - l = *(double *)lhs.ptr; - else - dmnsn_error(DMNSN_SEVERITY_HIGH, - "Invalid left hand side to binary operator."); - - if (rhs.type == DMNSN_AST_INTEGER) - r = *(long *)rhs.ptr; - else if (rhs.type == DMNSN_AST_FLOAT) - r = *(double *)rhs.ptr; - else - dmnsn_error(DMNSN_SEVERITY_HIGH, - "Invalid right hand side to binary operator."); - - double *res = malloc(sizeof(double)); - if (!res) - dmnsn_error(DMNSN_SEVERITY_HIGH, "Failed to allocate room for float."); - - switch (astnode.type) { - case DMNSN_AST_ADD: - *res = l + r; - break; - case DMNSN_AST_SUB: - *res = l - r; - break; - case DMNSN_AST_MUL: - *res = l*r; - break; - case DMNSN_AST_DIV: - *res = l/r; - break; - - default: - dmnsn_error(DMNSN_SEVERITY_HIGH, - "Attempt to evaluate wrong binary operator."); - } - - ret.type = DMNSN_AST_FLOAT; - ret.ptr = res; - } - - dmnsn_delete_astnode(lhs); - dmnsn_delete_astnode(rhs); - return ret; -} - -dmnsn_astnode -dmnsn_eval_scalar(dmnsn_astnode astnode) -{ - dmnsn_astnode ret; - - switch (astnode.type) { - case DMNSN_AST_INTEGER: - ret = dmnsn_copy_astnode(astnode); - ret.ptr = malloc(sizeof(long)); - if (!ret.ptr) - dmnsn_error(DMNSN_SEVERITY_HIGH, "Failed to allocate room for integer."); - - memcpy(ret.ptr, astnode.ptr, sizeof(long)); - return ret; - - case DMNSN_AST_FLOAT: - ret = dmnsn_copy_astnode(astnode); - ret.ptr = malloc(sizeof(double)); - if (!ret.ptr) - dmnsn_error(DMNSN_SEVERITY_HIGH, "Failed to allocate room for float."); - - memcpy(ret.ptr, astnode.ptr, sizeof(double)); - return ret; - - case DMNSN_AST_NEGATE: - return dmnsn_eval_scalar_unary(astnode); - - case DMNSN_AST_ADD: - case DMNSN_AST_SUB: - case DMNSN_AST_MUL: - case DMNSN_AST_DIV: - return dmnsn_eval_scalar_binary(astnode); - - default: - dmnsn_error(DMNSN_SEVERITY_HIGH, - "Given non-arithmetic-expression to evaluate."); - return astnode; /* Silence warning */ - } -} - -/* TODO */ -dmnsn_astnode dmnsn_eval_vector(dmnsn_astnode astnode); - -static void -dmnsn_print_astnode(FILE *file, dmnsn_astnode astnode) -{ - long ivalue; - double dvalue; - - switch (astnode.type) { - case DMNSN_AST_INTEGER: - ivalue = *(long *)astnode.ptr; - fprintf(file, "(%s %ld)", dmnsn_astnode_string(astnode.type), ivalue); - break; - - case DMNSN_AST_FLOAT: - dvalue = *(double *)astnode.ptr; - fprintf(file, "(%s %g)", dmnsn_astnode_string(astnode.type), dvalue); - break; - - default: - fprintf(file, "%s", dmnsn_astnode_string(astnode.type)); - } -} - -static void -dmnsn_print_astree(FILE *file, dmnsn_astnode astnode) -{ - unsigned int i; - dmnsn_astnode child; - - if (astnode.children && dmnsn_array_size(astnode.children) > 0) { - fprintf(file, "("); - dmnsn_print_astnode(file, astnode); - for (i = 0; i < dmnsn_array_size(astnode.children); ++i) { - dmnsn_array_get(astnode.children, i, &child); - fprintf(file, " "); - dmnsn_print_astree(file, child); - } - fprintf(file, ")"); - } else { - dmnsn_print_astnode(file, astnode); - } -} - -void -dmnsn_print_astree_sexpr(FILE *file, const dmnsn_array *astree) -{ - dmnsn_astnode astnode; - unsigned int i; - - if (dmnsn_array_size(astree) == 0) { - fprintf(file, "()"); - } else { - fprintf(file, "("); - dmnsn_array_get(astree, 0, &astnode); - dmnsn_print_astree(file, astnode); - - for (i = 1; i < dmnsn_array_size(astree); ++i) { - fprintf(file, " "); - dmnsn_array_get(astree, i, &astnode); - dmnsn_print_astree(file, astnode); - } - - fprintf(file, ")"); - } - - fprintf(file, "\n"); -} - -const char * -dmnsn_token_string(dmnsn_token_type token_type) -{ -#define TOKEN_SIZE 255 - static char token[TOKEN_SIZE + 1]; - - unsigned int i = YYTRANSLATE(token_type); - if (i > YYNTOKENS) { - fprintf(stderr, "Warning: unrecognised token %d.\n", (int)token_type); - return "unrecognized-token"; - } - - /* Trim the quotation marks */ - - if (strlen(yytname[i]) - 1 >= TOKEN_SIZE) { - fprintf(stderr, "Warning: name of token %d too long.\n", (int)token_type); - return "unrepresentable-token"; - } - - strcpy(token, yytname[i] + 1); - token[strlen(token) - 1] = '\0'; - - return token; -#undef TOKEN_SIZE -} - -const char * -dmnsn_astnode_string(dmnsn_astnode_type astnode_type) -{ - switch (astnode_type) { - /* Macro to shorten this switch */ -#define dmnsn_astnode_map(type, str) \ - case type: \ - return str; - - dmnsn_astnode_map(DMNSN_AST_FLOAT, "float"); - dmnsn_astnode_map(DMNSN_AST_INTEGER, "integer"); - dmnsn_astnode_map(DMNSN_AST_NEGATE, "-"); - dmnsn_astnode_map(DMNSN_AST_ADD, "+"); - dmnsn_astnode_map(DMNSN_AST_SUB, "-"); - dmnsn_astnode_map(DMNSN_AST_MUL, "*"); - dmnsn_astnode_map(DMNSN_AST_DIV, "/"); - dmnsn_astnode_map(DMNSN_AST_BOX, "box"); - dmnsn_astnode_map(DMNSN_AST_VECTOR, "vector"); - dmnsn_astnode_map(DMNSN_AST_SPHERE, "sphere"); - - default: - fprintf(stderr, "Warning: unrecognised astnode type %d.\n", - (int)astnode_type); - return "unrecognized-astnode"; - } -} diff --git a/dimension/flex.l b/dimension/flex.l deleted file mode 100644 index 2e2467c..0000000 --- a/dimension/flex.l +++ /dev/null @@ -1,291 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009 Tavian Barnes * - * * - * This file is part of Dimension. * - * * - * Dimension is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 3 of the License, or (at * - * your option) any later version. * - * * - * Dimension is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -%option reentrant stack yylineno noyywrap - -%{ -#define YY_DECL static int yylex(const char *filename, dmnsn_array *tokens, \ - yyscan_t yyscanner) -#include "tokenize.h" -#include "utility.h" -#include -#include -%} - -%x DMNSN_BLOCK_COMMENT -%x DMNSN_LINE_COMMENT -%x DMNSN_STRING -%x DMNSN_STRING_ESCAPE - -%% - -%{ -/* Some helpful macros that set fields of a token correctly, and other stuff */ - -#define NEW_TOKEN(token_type) \ - do { \ - token.type = token_type; \ - token.filename = filename; \ - token.line = yylineno; \ - token.col = yycolumn; \ - token.value = NULL; \ - } while (0) - -#define CALCULATE_COLUMN() yycolumn += yyleng - -#define PUSH() \ - do { \ - dmnsn_array_push(tokens, &token); \ - CALCULATE_COLUMN(); \ - } while (0) - -#define PUSH_TOKEN(token_type) \ - do { \ - NEW_TOKEN(token_type); \ - PUSH(); \ - } while (0) - -#define PUSH_VALUE_TOKEN(token_type) \ - do { \ - NEW_TOKEN(token_type); \ - token.value = strdup(yytext); \ - PUSH(); \ - } while (0) - -#define STRING_TOKEN() \ - do { \ - NEW_TOKEN(DMNSN_T_STRING); \ - string_length = 0; \ - string_extent = 8; \ - token.value = malloc(string_extent); \ - token.value[0] = '\0'; \ - CALCULATE_COLUMN(); \ - } while (0) - -#define STRCAT(str, len) \ - do { \ - if (string_length + len + 1 >= string_length) { \ - string_extent = 2*(string_length + len + 1); \ - token.value = realloc(token.value, string_extent); \ - } \ - \ - strncpy(token.value + string_length, str, len + 1); \ - string_length += len; \ - CALCULATE_COLUMN(); \ - } while(0) - -dmnsn_token token; -size_t string_length, string_extent; -unsigned long wchar; -%} - -(?# Comments) - -"/*" { - yy_push_state(DMNSN_BLOCK_COMMENT, yyscanner); - CALCULATE_COLUMN(); -} -"*/" CALCULATE_COLUMN(); yy_pop_state(yyscanner); -[^*/\n]* CALCULATE_COLUMN(); -"/" CALCULATE_COLUMN(); -"*" CALCULATE_COLUMN(); -\n ; - -"//" { - yy_push_state(DMNSN_LINE_COMMENT, yyscanner); - CALCULATE_COLUMN(); -} -\n ; yy_pop_state(yyscanner); -[^\n]+ CALCULATE_COLUMN(); - -(?# Punctuation) -"{" PUSH_TOKEN(DMNSN_T_LBRACE); -"}" PUSH_TOKEN(DMNSN_T_RBRACE); -"(" PUSH_TOKEN(DMNSN_T_LPAREN); -")" PUSH_TOKEN(DMNSN_T_RPAREN); -"[" PUSH_TOKEN(DMNSN_T_LBRACKET); -"]" PUSH_TOKEN(DMNSN_T_RBRACKET); -"+" PUSH_TOKEN(DMNSN_T_PLUS); -"-" PUSH_TOKEN(DMNSN_T_MINUS); -"*" PUSH_TOKEN(DMNSN_T_STAR); -"/" PUSH_TOKEN(DMNSN_T_SLASH); -"," PUSH_TOKEN(DMNSN_T_COMMA); -";" PUSH_TOKEN(DMNSN_T_SEMICOLON); -"?" PUSH_TOKEN(DMNSN_T_QUESTION); -":" PUSH_TOKEN(DMNSN_T_COLON); -"&" PUSH_TOKEN(DMNSN_T_AND); -"." PUSH_TOKEN(DMNSN_T_DOT); -"|" PUSH_TOKEN(DMNSN_T_PIPE); -"<" PUSH_TOKEN(DMNSN_T_LESS); -">" PUSH_TOKEN(DMNSN_T_GREATER); -"!" PUSH_TOKEN(DMNSN_T_BANG); -"=" PUSH_TOKEN(DMNSN_T_EQUALS); -"<=" PUSH_TOKEN(DMNSN_T_LESS_EQUAL); -">=" PUSH_TOKEN(DMNSN_T_GREATER_EQUAL); -"!=" PUSH_TOKEN(DMNSN_T_NOT_EQUAL); - -(?# Integers) -[[:digit:]]+ | -0(x|X)[[:digit:]aAbBcCdDeEfF]+ PUSH_VALUE_TOKEN(DMNSN_T_INTEGER); - -(?# Floats) -[[:digit:]]*\.?[[:digit:]]+((e|E)(\+|-)?[[:digit:]]+)? { - PUSH_VALUE_TOKEN(DMNSN_T_FLOAT); -} - -(?# Keywords) -"box" PUSH_TOKEN(DMNSN_T_BOX); -"camera" PUSH_TOKEN(DMNSN_T_CAMERA); -"color" PUSH_TOKEN(DMNSN_T_COLOR); -"colour" PUSH_TOKEN(DMNSN_T_COLOR); -"sphere" PUSH_TOKEN(DMNSN_T_SPHERE); - -(?# Directives) -"#include" PUSH_TOKEN(DMNSN_T_INCLUDE); -"#declare" PUSH_TOKEN(DMNSN_T_DECLARE); - -(?# Identifiers) -[[:alpha:]][[:alnum:]_]* PUSH_VALUE_TOKEN(DMNSN_T_IDENTIFIER); - -(?# Strings) - -"\"" STRING_TOKEN(); yy_push_state(DMNSN_STRING, yyscanner); -[^\\\"\n]* STRCAT(yytext, yyleng); -"\"" PUSH(); yy_pop_state(yyscanner); - -(?# String escape sequences) - -"\\" { - yy_push_state(DMNSN_STRING_ESCAPE, yyscanner); - CALCULATE_COLUMN(); -} -"a" STRCAT("\a", 1); yy_pop_state(yyscanner); -"b" STRCAT("\b", 1); yy_pop_state(yyscanner); -"f" STRCAT("\f", 1); yy_pop_state(yyscanner); -"n" STRCAT("\n", 1); yy_pop_state(yyscanner); -"r" STRCAT("\r", 1); yy_pop_state(yyscanner); -"t" STRCAT("\t", 1); yy_pop_state(yyscanner); -"v" STRCAT("\v", 1); yy_pop_state(yyscanner); -"\\" STRCAT("\\", 1); yy_pop_state(yyscanner); -"'" STRCAT("'", 1); yy_pop_state(yyscanner); -"\"" STRCAT("\"", 1); yy_pop_state(yyscanner); -"u"[[:digit:]aAbBcCdDeEfF]{4} { - wchar = strtoul(yytext + 1, NULL, 16); - STRCAT("", 2); - token.value[string_length - 2] = wchar/256; - token.value[string_length - 1] = wchar%256; - yy_pop_state(yyscanner); -} -. { - dmnsn_diagnostic(filename, yylineno, yycolumn, - "WARNING: unrecognised escape sequence '\\%c'", - (int)*yytext); - STRCAT(yytext, yyleng); - yy_pop_state(yyscanner); -} - -(?# Ignore whitespace) -[\b\r\t\v ]+ CALCULATE_COLUMN(); -\n ; - -(?# Fall-through) -. { - dmnsn_diagnostic(filename, yylineno, yycolumn, - "Unrecognized character '%c' (0x%X)", - (int)*yytext, (unsigned int)*yytext); - return 1; -} - -%% - -dmnsn_array * -dmnsn_tokenize(const char *filename, FILE *file) -{ - dmnsn_array *tokens = dmnsn_new_array(sizeof(dmnsn_token)); - - yyscan_t scanner; - - yylex_init(&scanner); - yyset_in(file, scanner); - - if (yylex(filename, tokens, scanner) != 0) { - dmnsn_delete_tokens(tokens); - tokens = NULL; - } - - yylex_destroy(scanner); - - return tokens; -} - -void -dmnsn_delete_tokens(dmnsn_array *tokens) -{ - dmnsn_token *token; - unsigned int i; - for (i = 0; i < dmnsn_array_size(tokens); ++i) { - token = dmnsn_array_at(tokens, i); - free(token->value); - } - dmnsn_delete_array(tokens); -} - -static void -dmnsn_print_token(FILE *file, dmnsn_token token) -{ - const char *tname; - if (token.type == DMNSN_T_LPAREN) { - tname = "\\("; - } else if (token.type == DMNSN_T_RPAREN) { - tname = "\\)"; - } else { - tname = dmnsn_token_string(token.type); - } - - if (token.value) { - fprintf(file, "(%s \"%s\")", tname, token.value); - } else { - fprintf(file, "%s", tname); - } -} - -void -dmnsn_print_token_sexpr(FILE *file, const dmnsn_array *tokens) -{ - dmnsn_token token; - unsigned int i; - - if (dmnsn_array_size(tokens) == 0) { - fprintf(file, "()"); - } else { - fprintf(file, "("); - dmnsn_array_get(tokens, 0, &token); - dmnsn_print_token(file, token); - - for (i = 1; i < dmnsn_array_size(tokens); ++i) { - fprintf(file, " "); - dmnsn_array_get(tokens, i, &token); - dmnsn_print_token(file, token); - } - - fprintf(file, ")"); - } - - fprintf(file, "\n"); -} diff --git a/dimension/grammar.y b/dimension/grammar.y new file mode 100644 index 0000000..426bc29 --- /dev/null +++ b/dimension/grammar.y @@ -0,0 +1,1119 @@ +/************************************************************************* + * Copyright (C) 2009 Tavian Barnes * + * * + * This file is part of Dimension. * + * * + * Dimension is free software; you can redistribute it and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; either version 3 of the License, or (at * + * your option) any later version. * + * * + * Dimension is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +%{ +#include "parse.h" +#include "tokenize.h" +#include "utility.h" +#include +#include + +typedef struct dmnsn_token_iterator { + const dmnsn_array *tokens; + unsigned int i; +} dmnsn_token_iterator; + +typedef struct dmnsn_location { + const char *first_filename, *last_filename; + int first_line, last_line; + int first_column, last_column; +} dmnsn_location; + +typedef union YYSTYPE { + const char *value; + dmnsn_astnode astnode; +} YYSTYPE; + +#define YYLTYPE dmnsn_location +#define YYLLOC_DEFAULT(Current, Rhs, N) \ + do { \ + if (N) { \ + (Current).first_filename = YYRHSLOC(Rhs, 1).first_filename; \ + (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \ + (Current).last_filename = YYRHSLOC(Rhs, N).last_filename; \ + (Current).last_line = YYRHSLOC(Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC(Rhs, N).last_column; \ + } else { \ + (Current).first_filename = (Current).last_filename = \ + YYRHSLOC(Rhs, 0).last_filename; \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC(Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC(Rhs, 0).last_column; \ + } \ + } while (0) + +/* Create a new astnode, populating filename, line, and col */ + +static dmnsn_astnode +dmnsn_copy_astnode(dmnsn_astnode astnode) +{ + dmnsn_astnode copy = { + .type = astnode.type, + .children = dmnsn_new_array(sizeof(dmnsn_astnode)), + .ptr = NULL, + .filename = astnode.filename, + .line = astnode.line, + .col = astnode.col + }; + return copy; +} + +static dmnsn_astnode +dmnsn_new_astnode(dmnsn_astnode_type type, YYLTYPE lloc) +{ + dmnsn_astnode astnode = { + .type = type, + .children = dmnsn_new_array(sizeof(dmnsn_astnode)), + .ptr = NULL, + .filename = lloc.first_filename, + .line = lloc.first_line, + .col = lloc.first_column + }; + return astnode; +} + +static dmnsn_astnode +dmnsn_new_astnode1(dmnsn_astnode_type type, YYLTYPE lloc, dmnsn_astnode n1) +{ + dmnsn_astnode astnode = dmnsn_new_astnode(type, lloc); + dmnsn_array_push(astnode.children, &n1); + return astnode; +} + +static dmnsn_astnode +dmnsn_new_astnode2(dmnsn_astnode_type type, YYLTYPE lloc, + dmnsn_astnode n1, dmnsn_astnode n2) +{ + dmnsn_astnode astnode = dmnsn_new_astnode(type, lloc); + dmnsn_array_push(astnode.children, &n1); + dmnsn_array_push(astnode.children, &n2); + return astnode; +} + +static dmnsn_astnode +dmnsn_new_astnode3(dmnsn_astnode_type type, YYLTYPE lloc, + dmnsn_astnode n1, dmnsn_astnode n2, dmnsn_astnode n3) +{ + dmnsn_astnode astnode = dmnsn_new_astnode(type, lloc); + dmnsn_array_push(astnode.children, &n1); + dmnsn_array_push(astnode.children, &n2); + dmnsn_array_push(astnode.children, &n3); + return astnode; +} + +/* Delete a single, unused astnode */ +static void +dmnsn_delete_astnode(dmnsn_astnode astnode) +{ + dmnsn_delete_astree(astnode.children); + free(astnode.ptr); +} + +static int +yylex(YYSTYPE *lvalp, YYLTYPE *llocp, dmnsn_token_iterator *iterator) +{ + if (iterator->i >= dmnsn_array_size(iterator->tokens)) { + return 0; + } else { + dmnsn_token token; + dmnsn_array_get(iterator->tokens, iterator->i, &token); + ++iterator->i; + + lvalp->value = token.value; + + llocp->first_filename = llocp->last_filename = token.filename; + llocp->first_line = llocp->last_line = token.line; + llocp->first_column = llocp->last_column = token.col; + + return token.type; + } +} + +void +yyerror(YYLTYPE *locp, dmnsn_array *astree, dmnsn_token_iterator *iterator, + const char *str) +{ + dmnsn_diagnostic(locp->first_filename, locp->first_line, locp->first_column, + "%s", str); +} +%} + +%define api.pure +%locations +%error-verbose +%token-table + +%parse-param {dmnsn_array *astree} +%parse-param {dmnsn_token_iterator *iterator} +%lex-param {dmnsn_token_iterator *iterator} + +%token END 0 "end-of-file" + +/* Punctuation */ +%token DMNSN_T_LBRACE "{" +%token DMNSN_T_RBRACE "}" +%token DMNSN_T_LPAREN "(" +%token DMNSN_T_RPAREN ")" +%token DMNSN_T_LBRACKET "[" +%token DMNSN_T_RBRACKET "]" +%token DMNSN_T_PLUS "+" +%token DMNSN_T_MINUS "-" +%token DMNSN_T_STAR "*" +%token DMNSN_T_SLASH "/" +%token DMNSN_T_COMMA "," +%token DMNSN_T_SEMICOLON ";" +%token DMNSN_T_QUESTION "?" +%token DMNSN_T_COLON ":" +%token DMNSN_T_AND "&" +%token DMNSN_T_DOT "." +%token DMNSN_T_PIPE "|" +%token DMNSN_T_LESS "<" +%token DMNSN_T_GREATER ">" +%token DMNSN_T_BANG "!" +%token DMNSN_T_EQUALS "=" +%token DMNSN_T_LESS_EQUAL "<=" +%token DMNSN_T_GREATER_EQUAL ">=" +%token DMNSN_T_NOT_EQUAL "!=" + +/* Numeric values */ +%token DMNSN_T_INTEGER "integer" +%token DMNSN_T_FLOAT "float" + +/* Keywords */ +%token DMNSN_T_AA_LEVEL +%token DMNSN_T_AA_THRESHOLD +%token DMNSN_T_ABS +%token DMNSN_T_ABSORPTION +%token DMNSN_T_ACCURACY +%token DMNSN_T_ACOS +%token DMNSN_T_ACOSH +%token DMNSN_T_ADAPTIVE +%token DMNSN_T_ADC_BAILOUT +%token DMNSN_T_AGATE +%token DMNSN_T_AGATE_TURB +%token DMNSN_T_ALL +%token DMNSN_T_ALL_INTERSECTIONS +%token DMNSN_T_ALPHA +%token DMNSN_T_ALTITUDE +%token DMNSN_T_ALWAYS_SAMPLE +%token DMNSN_T_AMBIENT +%token DMNSN_T_AMBIENT_LIGHT +%token DMNSN_T_ANGLE +%token DMNSN_T_APERTURE +%token DMNSN_T_APPEND +%token DMNSN_T_ARC_ANGLE +%token DMNSN_T_AREA_LIGHT +%token DMNSN_T_ARRAY +%token DMNSN_T_ASC +%token DMNSN_T_ASCII +%token DMNSN_T_ASIN +%token DMNSN_T_ASINH +%token DMNSN_T_ASSUMED_GAMMA +%token DMNSN_T_ATAN +%token DMNSN_T_ATAN2 +%token DMNSN_T_ATANH +%token DMNSN_T_AUTOSTOP +%token DMNSN_T_AVERAGE +%token DMNSN_T_B_SPLINE +%token DMNSN_T_BACKGROUND +%token DMNSN_T_BEZIER_SPLINE +%token DMNSN_T_BICUBIC_PATCH +%token DMNSN_T_BLACK_HOLE +%token DMNSN_T_BLOB +%token DMNSN_T_BLUE +%token DMNSN_T_BLUR_SAMPLES +%token DMNSN_T_BOUNDED_BY +%token DMNSN_T_BOX "box" +%token DMNSN_T_BOXED +%token DMNSN_T_BOZO +%token DMNSN_T_BRICK +%token DMNSN_T_BRICK_SIZE +%token DMNSN_T_BRIGHTNESS +%token DMNSN_T_BRILLIANCE +%token DMNSN_T_BUMP_MAP +%token DMNSN_T_BUMP_SIZE +%token DMNSN_T_BUMPS +%token DMNSN_T_CAMERA "camera" +%token DMNSN_T_CAUSTICS +%token DMNSN_T_CEIL +%token DMNSN_T_CELLS +%token DMNSN_T_CHARSET +%token DMNSN_T_CHECKER +%token DMNSN_T_CHR +%token DMNSN_T_CIRCULAR +%token DMNSN_T_CLIPPED_BY +%token DMNSN_T_CLOCK +%token DMNSN_T_CLOCK_DELTA +%token DMNSN_T_CLOCK_ON +%token DMNSN_T_COLLECT +%token DMNSN_T_COLOR "color" +%token DMNSN_T_COLOR_MAP +%token DMNSN_T_COMPONENT +%token DMNSN_T_COMPOSITE +%token DMNSN_T_CONCAT +%token DMNSN_T_CONE +%token DMNSN_T_CONFIDENCE +%token DMNSN_T_CONIC_SWEEP +%token DMNSN_T_CONSERVE_ENERGY +%token DMNSN_T_CONTAINED_BY +%token DMNSN_T_CONTROL0 +%token DMNSN_T_CONTROL1 +%token DMNSN_T_COORDS +%token DMNSN_T_COS +%token DMNSN_T_COSH +%token DMNSN_T_COUNT +%token DMNSN_T_CRACKLE +%token DMNSN_T_CRAND +%token DMNSN_T_CUBE +%token DMNSN_T_CUBIC +%token DMNSN_T_CUBIC_SPLINE +%token DMNSN_T_CUBIC_WAVE +%token DMNSN_T_CUTAWAY_TEXTURES +%token DMNSN_T_CYLINDER +%token DMNSN_T_CYLINDRICAL +%token DMNSN_T_DEFINED +%token DMNSN_T_DEGREES +%token DMNSN_T_DENSITY +%token DMNSN_T_DENSITY_FILE +%token DMNSN_T_DENSITY_MAP +%token DMNSN_T_DENTS +%token DMNSN_T_DF3 +%token DMNSN_T_DIFFERENCE +%token DMNSN_T_DIFFUSE +%token DMNSN_T_DIMENSION_SIZE +%token DMNSN_T_DIMENSIONS +%token DMNSN_T_DIRECTION +%token DMNSN_T_DISC +%token DMNSN_T_DISPERSION +%token DMNSN_T_DISPERSION_SAMPLES +%token DMNSN_T_DIST_EXP +%token DMNSN_T_DISTANCE +%token DMNSN_T_DIV +%token DMNSN_T_DOUBLE_ILLUMINATE +%token DMNSN_T_ECCENTRICITY +%token DMNSN_T_EMISSION +%token DMNSN_T_ERROR_BOUND +%token DMNSN_T_EVALUATE +%token DMNSN_T_EXP +%token DMNSN_T_EXPAND_THRESHOLDS +%token DMNSN_T_EXPONENT +%token DMNSN_T_EXTERIOR +%token DMNSN_T_EXTINCTION +%token DMNSN_T_FACE_INDICES +%token DMNSN_T_FACETS +%token DMNSN_T_FADE_COLOR +%token DMNSN_T_FADE_DISTANCE +%token DMNSN_T_FADE_POWER +%token DMNSN_T_FALLOFF +%token DMNSN_T_FALLOFF_ANGLE +%token DMNSN_T_FALSE +%token DMNSN_T_FILE_EXISTS +%token DMNSN_T_FILTER +%token DMNSN_T_FINAL_CLOCK +%token DMNSN_T_FINAL_FRAME +%token DMNSN_T_FINISH +%token DMNSN_T_FISHEYE +%token DMNSN_T_FLATNESS +%token DMNSN_T_FLIP +%token DMNSN_T_FLOOR +%token DMNSN_T_FOCAL_POINT +%token DMNSN_T_FOG +%token DMNSN_T_FOG_ALT +%token DMNSN_T_FOG_OFFSET +%token DMNSN_T_FOG_TYPE +%token DMNSN_T_FORM +%token DMNSN_T_FRAME_NUMBER +%token DMNSN_T_FREQUENCY +%token DMNSN_T_FRESNEL +%token DMNSN_T_FUNCTION +%token DMNSN_T_GATHER +%token DMNSN_T_GIF +%token DMNSN_T_GLOBAL_LIGHTS +%token DMNSN_T_GLOBAL_SETTINGS +%token DMNSN_T_GRADIENT +%token DMNSN_T_GRANITE +%token DMNSN_T_GRAY +%token DMNSN_T_GRAY_THRESHOLD +%token DMNSN_T_GREEN +%token DMNSN_T_HEIGHT_FIELD +%token DMNSN_T_HEXAGON +%token DMNSN_T_HF_GRAY_16 +%token DMNSN_T_HIERARCHY +%token DMNSN_T_HYPERCOMPLEX +%token DMNSN_T_HOLLOW +%token DMNSN_T_IFF +%token DMNSN_T_IMAGE_HEIGHT +%token DMNSN_T_IMAGE_MAP +%token DMNSN_T_IMAGE_PATTERN +%token DMNSN_T_IMAGE_WIDTH +%token DMNSN_T_INITIAL_CLOCK +%token DMNSN_T_INITIAL_FRAME +%token DMNSN_T_INSIDE +%token DMNSN_T_INSIDE_VECTOR +%token DMNSN_T_INT +%token DMNSN_T_INTERIOR +%token DMNSN_T_INTERIOR_TEXTURE +%token DMNSN_T_INTERNAL +%token DMNSN_T_INTERPOLATE +%token DMNSN_T_INTERSECTION +%token DMNSN_T_INTERVALS +%token DMNSN_T_INVERSE +%token DMNSN_T_IOR +%token DMNSN_T_IRID +%token DMNSN_T_IRID_WAVELENGTH +%token DMNSN_T_ISOSURFACE +%token DMNSN_T_JITTER +%token DMNSN_T_JPEG +%token DMNSN_T_JULIA +%token DMNSN_T_JULIA_FRACTAL +%token DMNSN_T_LAMBDA +%token DMNSN_T_LATHE +%token DMNSN_T_LEOPARD +%token DMNSN_T_LIGHT_GROUP +%token DMNSN_T_LIGHT_SOURCE +%token DMNSN_T_LINEAR_SPLINE +%token DMNSN_T_LINEAR_SWEEP +%token DMNSN_T_LN +%token DMNSN_T_LOAD_FILE +%token DMNSN_T_LOCATION +%token DMNSN_T_LOG +%token DMNSN_T_LOOK_AT +%token DMNSN_T_LOOKS_LIKE +%token DMNSN_T_LOW_ERROR_FACTOR +%token DMNSN_T_MAGNET +%token DMNSN_T_MAJOR_RADIUS +%token DMNSN_T_MANDEL +%token DMNSN_T_MAP_TYPE +%token DMNSN_T_MARBLE +%token DMNSN_T_MATERIAL +%token DMNSN_T_MATERIAL_MAP +%token DMNSN_T_MATRIX +%token DMNSN_T_MAX +%token DMNSN_T_MAX_EXTENT +%token DMNSN_T_MAX_GRADIENT +%token DMNSN_T_MAX_INTERSECTIONS +%token DMNSN_T_MAX_ITERATION +%token DMNSN_T_MAX_SAMPLE +%token DMNSN_T_MAX_TRACE +%token DMNSN_T_MAX_TRACE_LEVEL +%token DMNSN_T_MEDIA +%token DMNSN_T_MEDIA_ATTENUATION +%token DMNSN_T_MEDIA_INTERACTION +%token DMNSN_T_MERGE +%token DMNSN_T_MESH +%token DMNSN_T_MESH2 +%token DMNSN_T_METALLIC +%token DMNSN_T_METHOD +%token DMNSN_T_METRIC +%token DMNSN_T_MIN +%token DMNSN_T_MIN_EXTENT +%token DMNSN_T_MINIMUM_REUSE +%token DMNSN_T_MOD +%token DMNSN_T_MORTAR +%token DMNSN_T_NATURAL_SPLINE +%token DMNSN_T_NEAREST_COUNT +%token DMNSN_T_NO +%token DMNSN_T_NO_BUMP_SCALE +%token DMNSN_T_NO_IMAGE +%token DMNSN_T_NO_REFLECTION +%token DMNSN_T_NO_SHADOW +%token DMNSN_T_NOISE_GENERATOR +%token DMNSN_T_NORMAL +%token DMNSN_T_NORMAL_INDICES +%token DMNSN_T_NORMAL_MAP +%token DMNSN_T_NORMAL_VECTORS +%token DMNSN_T_NUMBER_OF_WAVES +%token DMNSN_T_OBJECT +%token DMNSN_T_OCTAVES +%token DMNSN_T_OFF +%token DMNSN_T_OFFSET +%token DMNSN_T_OMEGA +%token DMNSN_T_OMNIMAX +%token DMNSN_T_ON +%token DMNSN_T_ONCE +%token DMNSN_T_ONION +%token DMNSN_T_OPEN +%token DMNSN_T_ORIENT +%token DMNSN_T_ORIENTATION +%token DMNSN_T_ORTHOGRAPHIC +%token DMNSN_T_PANORAMIC +%token DMNSN_T_PARALLEL +%token DMNSN_T_PARAMETRIC +%token DMNSN_T_PASS_THROUGH +%token DMNSN_T_PATTERN +%token DMNSN_T_PERSPECTIVE +%token DMNSN_T_PGM +%token DMNSN_T_PHASE +%token DMNSN_T_PHONG +%token DMNSN_T_PHONG_SIZE +%token DMNSN_T_PHOTONS +%token DMNSN_T_PI +%token DMNSN_T_PIGMENT +%token DMNSN_T_PIGMENT_MAP +%token DMNSN_T_PIGMENT_PATTERN +%token DMNSN_T_PLANAR +%token DMNSN_T_PLANE +%token DMNSN_T_PNG +%token DMNSN_T_POINT_AT +%token DMNSN_T_POLY +%token DMNSN_T_POLY_WAVE +%token DMNSN_T_POLYGON +%token DMNSN_T_POT +%token DMNSN_T_POW +%token DMNSN_T_PPM +%token DMNSN_T_PRECISION +%token DMNSN_T_PRECOMPUTE +%token DMNSN_T_PRETRACE_END +%token DMNSN_T_PRETRACE_START +%token DMNSN_T_PRISM +%token DMNSN_T_PROD +%token DMNSN_T_PROJECTED_THROUGH +%token DMNSN_T_PWR +%token DMNSN_T_QUADRATIC_SPLINE +%token DMNSN_T_QUADRIC +%token DMNSN_T_QUARTIC +%token DMNSN_T_QUATERNION +%token DMNSN_T_QUICK_COLOR +%token DMNSN_T_QUILTED +%token DMNSN_T_RADIAL +%token DMNSN_T_RADIANS +%token DMNSN_T_RADIOSITY +%token DMNSN_T_RADIUS +%token DMNSN_T_RAINBOW +%token DMNSN_T_RAMP_WAVE +%token DMNSN_T_RAND +%token DMNSN_T_RATIO +%token DMNSN_T_RECIPROCAL +%token DMNSN_T_RECURSION_LIMIT +%token DMNSN_T_RED +%token DMNSN_T_REFLECTION +%token DMNSN_T_REFLECTION_EXPONENT +%token DMNSN_T_REFRACTION +%token DMNSN_T_REPEAT +%token DMNSN_T_RGB +%token DMNSN_T_RGBF +%token DMNSN_T_RGBFT +%token DMNSN_T_RGBT +%token DMNSN_T_RIGHT +%token DMNSN_T_RIPPLES +%token DMNSN_T_ROTATE +%token DMNSN_T_ROUGHNESS +%token DMNSN_T_SAMPLES +%token DMNSN_T_SAVE_FILE +%token DMNSN_T_SCALE +%token DMNSN_T_SCALLOP_WAVE +%token DMNSN_T_SCATTERING +%token DMNSN_T_SEED +%token DMNSN_T_SELECT +%token DMNSN_T_SHADOWLESS +%token DMNSN_T_SIN +%token DMNSN_T_SINE_WAVE +%token DMNSN_T_SINH +%token DMNSN_T_SIZE +%token DMNSN_T_SKY +%token DMNSN_T_SKY_SPHERE +%token DMNSN_T_SLICE +%token DMNSN_T_SLOPE +%token DMNSN_T_SLOPE_MAP +%token DMNSN_T_SMOOTH +%token DMNSN_T_SMOOTH_TRIANGLE +%token DMNSN_T_SOLID +%token DMNSN_T_SOR +%token DMNSN_T_SPACING +%token DMNSN_T_SPECULAR +%token DMNSN_T_SPHERE "sphere" +%token DMNSN_T_SPHERE_SWEEP +%token DMNSN_T_SPHERICAL +%token DMNSN_T_SPIRAL1 +%token DMNSN_T_SPIRAL2 +%token DMNSN_T_SPLINE +%token DMNSN_T_SPLIT_UNION +%token DMNSN_T_SPOTLIGHT +%token DMNSN_T_SPOTTED +%token DMNSN_T_SQR +%token DMNSN_T_SQRT +%token DMNSN_T_STR +%token DMNSN_T_STRCMP +%token DMNSN_T_STRENGTH +%token DMNSN_T_STRLEN +%token DMNSN_T_STRLWR +%token DMNSN_T_STRUPR +%token DMNSN_T_STURM +%token DMNSN_T_SUBSTR +%token DMNSN_T_SUM +%token DMNSN_T_SUPERELLIPSOID +%token DMNSN_T_SYS +%token DMNSN_T_T +%token DMNSN_T_TAN +%token DMNSN_T_TANH +%token DMNSN_T_TARGET +%token DMNSN_T_TEXT +%token DMNSN_T_TEXTURE +%token DMNSN_T_TEXTURE_LIST +%token DMNSN_T_TEXTURE_MAP +%token DMNSN_T_TGA +%token DMNSN_T_THICKNESS +%token DMNSN_T_THRESHOLD +%token DMNSN_T_TIFF +%token DMNSN_T_TIGHTNESS +%token DMNSN_T_TILE2 +%token DMNSN_T_TILES +%token DMNSN_T_TOLERANCE +%token DMNSN_T_TOROIDAL +%token DMNSN_T_TORUS +%token DMNSN_T_TRACE +%token DMNSN_T_TRANSFORM +%token DMNSN_T_TRANSLATE +%token DMNSN_T_TRANSMIT +%token DMNSN_T_TRIANGLE +%token DMNSN_T_TRIANGLE_WAVE +%token DMNSN_T_TRUE +%token DMNSN_T_TTF +%token DMNSN_T_TURB_DEPTH +%token DMNSN_T_TURBULENCE +%token DMNSN_T_TYPE +%token DMNSN_T_U +%token DMNSN_T_U_STEPS +%token DMNSN_T_ULTRA_WIDE_ANGLE +%token DMNSN_T_UNION +%token DMNSN_T_UP +%token DMNSN_T_USE_ALPHA +%token DMNSN_T_USE_COLOR +%token DMNSN_T_USE_INDEX +%token DMNSN_T_UTF8 +%token DMNSN_T_UV_INDICES +%token DMNSN_T_UV_MAPPING +%token DMNSN_T_UV_VECTORS +%token DMNSN_T_V +%token DMNSN_T_V_STEPS +%token DMNSN_T_VAL +%token DMNSN_T_VARIANCE +%token DMNSN_T_VAXIS_ROTATE +%token DMNSN_T_VCROSS +%token DMNSN_T_VDOT +%token DMNSN_T_VERTEX_VECTORS +%token DMNSN_T_VLENGTH +%token DMNSN_T_VNORMALIZE +%token DMNSN_T_VROTATE +%token DMNSN_T_VSTR +%token DMNSN_T_VTURBULENCE +%token DMNSN_T_WARP +%token DMNSN_T_WATER_LEVEL +%token DMNSN_T_WAVES +%token DMNSN_T_WIDTH +%token DMNSN_T_WOOD +%token DMNSN_T_WRINKLES +%token DMNSN_T_X +%token DMNSN_T_Y +%token DMNSN_T_YES +%token DMNSN_T_Z + +/* Directives (#declare etc.) */ +%token DMNSN_T_BREAK +%token DMNSN_T_CASE +%token DMNSN_T_DEBUG +%token DMNSN_T_DECLARE "#declare" +%token DMNSN_T_DEFAULT +%token DMNSN_T_ELSE +%token DMNSN_T_END +%token DMNSN_T_ERROR +%token DMNSN_T_FCLOSE +%token DMNSN_T_FOPEN +%token DMNSN_T_IF +%token DMNSN_T_IFDEF +%token DMNSN_T_IFNDEF +%token DMNSN_T_INCLUDE "#include" +%token DMNSN_T_LOCAL +%token DMNSN_T_MACRO +%token DMNSN_T_RANGE +%token DMNSN_T_READ +%token DMNSN_T_RENDER +%token DMNSN_T_STATISTICS +%token DMNSN_T_SWITCH +%token DMNSN_T_UNDEF +%token DMNSN_T_VERSION +%token DMNSN_T_WARNING +%token DMNSN_T_WHILE +%token DMNSN_T_WRITE + +/* Identifiers */ +%token DMNSN_T_IDENTIFIER "identifier" + +/* Strings */ +%token DMNSN_T_STRING "string" + +/* Top-level items */ +%type SCENE_ITEM + +/* Objects */ +%type OBJECT +%type FINITE_SOLID_OBJECT +%type BOX +%type SPHERE + +/* Floats */ +%type FLOAT +%type FLOAT_TERM +%type FLOAT_FACTOR +%type FLOAT_LITERAL + +/* Vectors */ +%type VECTOR +%type VECTOR_LITERAL + +%destructor { dmnsn_delete_astnode($$); } + +%% + +SCENE: /* empty */ { } + | SCENE SCENE_ITEM { + dmnsn_array_push(astree, &$2); + } +; + +SCENE_ITEM: OBJECT +; + +OBJECT: FINITE_SOLID_OBJECT +; + +FINITE_SOLID_OBJECT: BOX + | SPHERE +; + +BOX: "box" "{" + VECTOR "," VECTOR + "}" + { + $$ = dmnsn_new_astnode2(DMNSN_AST_BOX, @$, $3, $5); + } +; + +SPHERE: "sphere" "{" + VECTOR "," FLOAT + "}" + { + $$ = dmnsn_new_astnode2(DMNSN_AST_SPHERE, @$, $3, $5); + } +; + +FLOAT: FLOAT_TERM + { + $$ = dmnsn_eval_scalar($1); + dmnsn_delete_astnode($1); + } + | FLOAT "+" FLOAT_TERM + { + dmnsn_astnode sum = dmnsn_new_astnode2(DMNSN_AST_ADD, @$, $1, $3); + $$ = dmnsn_eval_scalar(sum); + dmnsn_delete_astnode(sum); + } + | FLOAT "-" FLOAT_TERM + { + dmnsn_astnode diff = dmnsn_new_astnode2(DMNSN_AST_SUB, @$, $1, $3); + $$ = dmnsn_eval_scalar(diff); + dmnsn_delete_astnode(diff); + } +; + +FLOAT_TERM: FLOAT_FACTOR + | FLOAT_TERM "*" FLOAT_FACTOR + { + $$ = dmnsn_new_astnode2(DMNSN_AST_MUL, @$, $1, $3); + } + | FLOAT_TERM "/" FLOAT_FACTOR + { + $$ = dmnsn_new_astnode2(DMNSN_AST_DIV, @$, $1, $3); + } + +FLOAT_FACTOR: FLOAT_LITERAL + | "+" FLOAT_FACTOR { $$ = $2; } + | "-" FLOAT_FACTOR + { + $$ = dmnsn_new_astnode1(DMNSN_AST_NEGATE, @$, $2); + } + | "(" FLOAT ")" { $$ = $2; } + +FLOAT_LITERAL: "integer" + { + $$ = dmnsn_new_astnode(DMNSN_AST_INTEGER, @$); + $$.ptr = malloc(sizeof(long)); + if (!$$.ptr) + dmnsn_error(DMNSN_SEVERITY_HIGH, + "Failed to allocate room for integer."); + + *(long *)$$.ptr = strtol($1, NULL, 0); + } + | "float" + { + $$ = dmnsn_new_astnode(DMNSN_AST_FLOAT, @$); + $$.ptr = malloc(sizeof(double)); + if (!$$.ptr) + dmnsn_error(DMNSN_SEVERITY_HIGH, + "Failed to allocate room for float."); + + *(double *)$$.ptr = strtod($1, NULL); + } +; + +VECTOR: VECTOR_LITERAL +; + +VECTOR_LITERAL: "<" FLOAT "," FLOAT "," FLOAT ">" + { + $$ = dmnsn_new_astnode3(DMNSN_AST_VECTOR, @$, $2, $4, $6); + } +; + +%% + +dmnsn_array * +dmnsn_parse(const dmnsn_array *tokens) +{ + dmnsn_array *astree = dmnsn_new_array(sizeof(dmnsn_astnode)); + dmnsn_token_iterator iterator = { .tokens = tokens, .i = 0 }; + + if (yyparse(astree, &iterator) != 0) { + dmnsn_delete_astree(astree); + return NULL; + } + + return astree; +} + +void +dmnsn_delete_astree(dmnsn_array *astree) +{ + unsigned int i; + dmnsn_astnode node; + + if (astree) { + for (i = 0; i < dmnsn_array_size(astree); ++i) { + dmnsn_array_get(astree, i, &node); + dmnsn_delete_astree(node.children); + free(node.ptr); + } + dmnsn_delete_array(astree); + } +} + +static dmnsn_astnode +dmnsn_eval_scalar_unary(dmnsn_astnode astnode) +{ + dmnsn_astnode ret = dmnsn_copy_astnode(astnode), rhs; + dmnsn_array_get(astnode.children, 0, &rhs); + rhs = dmnsn_eval_scalar(rhs); + + if (rhs.type == DMNSN_AST_INTEGER) { + long n = *(long *)rhs.ptr; + long *res = malloc(sizeof(long)); + if (!res) + dmnsn_error(DMNSN_SEVERITY_HIGH, "Failed to allocate room for integer."); + + switch(astnode.type) { + case DMNSN_AST_NEGATE: + *res = -n; + break; + + default: + dmnsn_error(DMNSN_SEVERITY_HIGH, + "Attempt to evaluate wrong unary operator."); + } + + ret.type = DMNSN_AST_INTEGER; + ret.ptr = res; + } else if (rhs.type == DMNSN_AST_FLOAT) { + double n = *(double *)rhs.ptr; + double *res = malloc(sizeof(double)); + if (!res) + dmnsn_error(DMNSN_SEVERITY_HIGH, "Failed to allocate room for float."); + + switch(astnode.type) { + case DMNSN_AST_NEGATE: + *res = -n; + break; + + default: + dmnsn_error(DMNSN_SEVERITY_HIGH, + "Attempt to evaluate wrong unary operator."); + } + + ret.type = DMNSN_AST_FLOAT; + ret.ptr = res; + } else { + dmnsn_error(DMNSN_SEVERITY_HIGH, + "Invalid right hand side to unary operator."); + } + + dmnsn_delete_astnode(rhs); + return ret; +} + +static dmnsn_astnode +dmnsn_eval_scalar_binary(dmnsn_astnode astnode) +{ + dmnsn_astnode ret = dmnsn_copy_astnode(astnode), lhs, rhs; + dmnsn_array_get(astnode.children, 0, &lhs); + dmnsn_array_get(astnode.children, 1, &rhs); + lhs = dmnsn_eval_scalar(lhs); + rhs = dmnsn_eval_scalar(rhs); + + if (lhs.type == DMNSN_AST_INTEGER && rhs.type == DMNSN_AST_INTEGER + && astnode.type != DMNSN_AST_DIV) { + long l, r; + l = *(long *)lhs.ptr; + r = *(long *)rhs.ptr; + + long *res = malloc(sizeof(long)); + if (!res) + dmnsn_error(DMNSN_SEVERITY_HIGH, "Failed to allocate room for integer."); + + switch (astnode.type) { + case DMNSN_AST_ADD: + *res = l + r; + break; + case DMNSN_AST_SUB: + *res = l - r; + break; + case DMNSN_AST_MUL: + *res = l*r; + break; + + default: + dmnsn_error(DMNSN_SEVERITY_HIGH, + "Attempt to evaluate wrong binary operator."); + } + + ret.type = DMNSN_AST_INTEGER; + ret.ptr = res; + } else { + double l = 0.0, r = 0.0; + + if (lhs.type == DMNSN_AST_INTEGER) + l = *(long *)lhs.ptr; + else if (lhs.type == DMNSN_AST_FLOAT) + l = *(double *)lhs.ptr; + else + dmnsn_error(DMNSN_SEVERITY_HIGH, + "Invalid left hand side to binary operator."); + + if (rhs.type == DMNSN_AST_INTEGER) + r = *(long *)rhs.ptr; + else if (rhs.type == DMNSN_AST_FLOAT) + r = *(double *)rhs.ptr; + else + dmnsn_error(DMNSN_SEVERITY_HIGH, + "Invalid right hand side to binary operator."); + + double *res = malloc(sizeof(double)); + if (!res) + dmnsn_error(DMNSN_SEVERITY_HIGH, "Failed to allocate room for float."); + + switch (astnode.type) { + case DMNSN_AST_ADD: + *res = l + r; + break; + case DMNSN_AST_SUB: + *res = l - r; + break; + case DMNSN_AST_MUL: + *res = l*r; + break; + case DMNSN_AST_DIV: + *res = l/r; + break; + + default: + dmnsn_error(DMNSN_SEVERITY_HIGH, + "Attempt to evaluate wrong binary operator."); + } + + ret.type = DMNSN_AST_FLOAT; + ret.ptr = res; + } + + dmnsn_delete_astnode(lhs); + dmnsn_delete_astnode(rhs); + return ret; +} + +dmnsn_astnode +dmnsn_eval_scalar(dmnsn_astnode astnode) +{ + dmnsn_astnode ret; + + switch (astnode.type) { + case DMNSN_AST_INTEGER: + ret = dmnsn_copy_astnode(astnode); + ret.ptr = malloc(sizeof(long)); + if (!ret.ptr) + dmnsn_error(DMNSN_SEVERITY_HIGH, "Failed to allocate room for integer."); + + memcpy(ret.ptr, astnode.ptr, sizeof(long)); + return ret; + + case DMNSN_AST_FLOAT: + ret = dmnsn_copy_astnode(astnode); + ret.ptr = malloc(sizeof(double)); + if (!ret.ptr) + dmnsn_error(DMNSN_SEVERITY_HIGH, "Failed to allocate room for float."); + + memcpy(ret.ptr, astnode.ptr, sizeof(double)); + return ret; + + case DMNSN_AST_NEGATE: + return dmnsn_eval_scalar_unary(astnode); + + case DMNSN_AST_ADD: + case DMNSN_AST_SUB: + case DMNSN_AST_MUL: + case DMNSN_AST_DIV: + return dmnsn_eval_scalar_binary(astnode); + + default: + dmnsn_error(DMNSN_SEVERITY_HIGH, + "Given non-arithmetic-expression to evaluate."); + return astnode; /* Silence warning */ + } +} + +/* TODO */ +dmnsn_astnode dmnsn_eval_vector(dmnsn_astnode astnode); + +static void +dmnsn_print_astnode(FILE *file, dmnsn_astnode astnode) +{ + long ivalue; + double dvalue; + + switch (astnode.type) { + case DMNSN_AST_INTEGER: + ivalue = *(long *)astnode.ptr; + fprintf(file, "(%s %ld)", dmnsn_astnode_string(astnode.type), ivalue); + break; + + case DMNSN_AST_FLOAT: + dvalue = *(double *)astnode.ptr; + fprintf(file, "(%s %g)", dmnsn_astnode_string(astnode.type), dvalue); + break; + + default: + fprintf(file, "%s", dmnsn_astnode_string(astnode.type)); + } +} + +static void +dmnsn_print_astree(FILE *file, dmnsn_astnode astnode) +{ + unsigned int i; + dmnsn_astnode child; + + if (astnode.children && dmnsn_array_size(astnode.children) > 0) { + fprintf(file, "("); + dmnsn_print_astnode(file, astnode); + for (i = 0; i < dmnsn_array_size(astnode.children); ++i) { + dmnsn_array_get(astnode.children, i, &child); + fprintf(file, " "); + dmnsn_print_astree(file, child); + } + fprintf(file, ")"); + } else { + dmnsn_print_astnode(file, astnode); + } +} + +void +dmnsn_print_astree_sexpr(FILE *file, const dmnsn_array *astree) +{ + dmnsn_astnode astnode; + unsigned int i; + + if (dmnsn_array_size(astree) == 0) { + fprintf(file, "()"); + } else { + fprintf(file, "("); + dmnsn_array_get(astree, 0, &astnode); + dmnsn_print_astree(file, astnode); + + for (i = 1; i < dmnsn_array_size(astree); ++i) { + fprintf(file, " "); + dmnsn_array_get(astree, i, &astnode); + dmnsn_print_astree(file, astnode); + } + + fprintf(file, ")"); + } + + fprintf(file, "\n"); +} + +const char * +dmnsn_token_string(dmnsn_token_type token_type) +{ +#define TOKEN_SIZE 255 + static char token[TOKEN_SIZE + 1]; + + unsigned int i = YYTRANSLATE(token_type); + if (i > YYNTOKENS) { + fprintf(stderr, "Warning: unrecognised token %d.\n", (int)token_type); + return "unrecognized-token"; + } + + /* Trim the quotation marks */ + + if (strlen(yytname[i]) - 1 >= TOKEN_SIZE) { + fprintf(stderr, "Warning: name of token %d too long.\n", (int)token_type); + return "unrepresentable-token"; + } + + strcpy(token, yytname[i] + 1); + token[strlen(token) - 1] = '\0'; + + return token; +#undef TOKEN_SIZE +} + +const char * +dmnsn_astnode_string(dmnsn_astnode_type astnode_type) +{ + switch (astnode_type) { + /* Macro to shorten this switch */ +#define dmnsn_astnode_map(type, str) \ + case type: \ + return str; + + dmnsn_astnode_map(DMNSN_AST_FLOAT, "float"); + dmnsn_astnode_map(DMNSN_AST_INTEGER, "integer"); + dmnsn_astnode_map(DMNSN_AST_NEGATE, "-"); + dmnsn_astnode_map(DMNSN_AST_ADD, "+"); + dmnsn_astnode_map(DMNSN_AST_SUB, "-"); + dmnsn_astnode_map(DMNSN_AST_MUL, "*"); + dmnsn_astnode_map(DMNSN_AST_DIV, "/"); + dmnsn_astnode_map(DMNSN_AST_BOX, "box"); + dmnsn_astnode_map(DMNSN_AST_VECTOR, "vector"); + dmnsn_astnode_map(DMNSN_AST_SPHERE, "sphere"); + + default: + fprintf(stderr, "Warning: unrecognised astnode type %d.\n", + (int)astnode_type); + return "unrecognized-astnode"; + } +} diff --git a/dimension/lexer.l b/dimension/lexer.l new file mode 100644 index 0000000..2e2467c --- /dev/null +++ b/dimension/lexer.l @@ -0,0 +1,291 @@ +/************************************************************************* + * Copyright (C) 2009 Tavian Barnes * + * * + * This file is part of Dimension. * + * * + * Dimension is free software; you can redistribute it and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; either version 3 of the License, or (at * + * your option) any later version. * + * * + * Dimension is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +%option reentrant stack yylineno noyywrap + +%{ +#define YY_DECL static int yylex(const char *filename, dmnsn_array *tokens, \ + yyscan_t yyscanner) +#include "tokenize.h" +#include "utility.h" +#include +#include +%} + +%x DMNSN_BLOCK_COMMENT +%x DMNSN_LINE_COMMENT +%x DMNSN_STRING +%x DMNSN_STRING_ESCAPE + +%% + +%{ +/* Some helpful macros that set fields of a token correctly, and other stuff */ + +#define NEW_TOKEN(token_type) \ + do { \ + token.type = token_type; \ + token.filename = filename; \ + token.line = yylineno; \ + token.col = yycolumn; \ + token.value = NULL; \ + } while (0) + +#define CALCULATE_COLUMN() yycolumn += yyleng + +#define PUSH() \ + do { \ + dmnsn_array_push(tokens, &token); \ + CALCULATE_COLUMN(); \ + } while (0) + +#define PUSH_TOKEN(token_type) \ + do { \ + NEW_TOKEN(token_type); \ + PUSH(); \ + } while (0) + +#define PUSH_VALUE_TOKEN(token_type) \ + do { \ + NEW_TOKEN(token_type); \ + token.value = strdup(yytext); \ + PUSH(); \ + } while (0) + +#define STRING_TOKEN() \ + do { \ + NEW_TOKEN(DMNSN_T_STRING); \ + string_length = 0; \ + string_extent = 8; \ + token.value = malloc(string_extent); \ + token.value[0] = '\0'; \ + CALCULATE_COLUMN(); \ + } while (0) + +#define STRCAT(str, len) \ + do { \ + if (string_length + len + 1 >= string_length) { \ + string_extent = 2*(string_length + len + 1); \ + token.value = realloc(token.value, string_extent); \ + } \ + \ + strncpy(token.value + string_length, str, len + 1); \ + string_length += len; \ + CALCULATE_COLUMN(); \ + } while(0) + +dmnsn_token token; +size_t string_length, string_extent; +unsigned long wchar; +%} + +(?# Comments) + +"/*" { + yy_push_state(DMNSN_BLOCK_COMMENT, yyscanner); + CALCULATE_COLUMN(); +} +"*/" CALCULATE_COLUMN(); yy_pop_state(yyscanner); +[^*/\n]* CALCULATE_COLUMN(); +"/" CALCULATE_COLUMN(); +"*" CALCULATE_COLUMN(); +\n ; + +"//" { + yy_push_state(DMNSN_LINE_COMMENT, yyscanner); + CALCULATE_COLUMN(); +} +\n ; yy_pop_state(yyscanner); +[^\n]+ CALCULATE_COLUMN(); + +(?# Punctuation) +"{" PUSH_TOKEN(DMNSN_T_LBRACE); +"}" PUSH_TOKEN(DMNSN_T_RBRACE); +"(" PUSH_TOKEN(DMNSN_T_LPAREN); +")" PUSH_TOKEN(DMNSN_T_RPAREN); +"[" PUSH_TOKEN(DMNSN_T_LBRACKET); +"]" PUSH_TOKEN(DMNSN_T_RBRACKET); +"+" PUSH_TOKEN(DMNSN_T_PLUS); +"-" PUSH_TOKEN(DMNSN_T_MINUS); +"*" PUSH_TOKEN(DMNSN_T_STAR); +"/" PUSH_TOKEN(DMNSN_T_SLASH); +"," PUSH_TOKEN(DMNSN_T_COMMA); +";" PUSH_TOKEN(DMNSN_T_SEMICOLON); +"?" PUSH_TOKEN(DMNSN_T_QUESTION); +":" PUSH_TOKEN(DMNSN_T_COLON); +"&" PUSH_TOKEN(DMNSN_T_AND); +"." PUSH_TOKEN(DMNSN_T_DOT); +"|" PUSH_TOKEN(DMNSN_T_PIPE); +"<" PUSH_TOKEN(DMNSN_T_LESS); +">" PUSH_TOKEN(DMNSN_T_GREATER); +"!" PUSH_TOKEN(DMNSN_T_BANG); +"=" PUSH_TOKEN(DMNSN_T_EQUALS); +"<=" PUSH_TOKEN(DMNSN_T_LESS_EQUAL); +">=" PUSH_TOKEN(DMNSN_T_GREATER_EQUAL); +"!=" PUSH_TOKEN(DMNSN_T_NOT_EQUAL); + +(?# Integers) +[[:digit:]]+ | +0(x|X)[[:digit:]aAbBcCdDeEfF]+ PUSH_VALUE_TOKEN(DMNSN_T_INTEGER); + +(?# Floats) +[[:digit:]]*\.?[[:digit:]]+((e|E)(\+|-)?[[:digit:]]+)? { + PUSH_VALUE_TOKEN(DMNSN_T_FLOAT); +} + +(?# Keywords) +"box" PUSH_TOKEN(DMNSN_T_BOX); +"camera" PUSH_TOKEN(DMNSN_T_CAMERA); +"color" PUSH_TOKEN(DMNSN_T_COLOR); +"colour" PUSH_TOKEN(DMNSN_T_COLOR); +"sphere" PUSH_TOKEN(DMNSN_T_SPHERE); + +(?# Directives) +"#include" PUSH_TOKEN(DMNSN_T_INCLUDE); +"#declare" PUSH_TOKEN(DMNSN_T_DECLARE); + +(?# Identifiers) +[[:alpha:]][[:alnum:]_]* PUSH_VALUE_TOKEN(DMNSN_T_IDENTIFIER); + +(?# Strings) + +"\"" STRING_TOKEN(); yy_push_state(DMNSN_STRING, yyscanner); +[^\\\"\n]* STRCAT(yytext, yyleng); +"\"" PUSH(); yy_pop_state(yyscanner); + +(?# String escape sequences) + +"\\" { + yy_push_state(DMNSN_STRING_ESCAPE, yyscanner); + CALCULATE_COLUMN(); +} +"a" STRCAT("\a", 1); yy_pop_state(yyscanner); +"b" STRCAT("\b", 1); yy_pop_state(yyscanner); +"f" STRCAT("\f", 1); yy_pop_state(yyscanner); +"n" STRCAT("\n", 1); yy_pop_state(yyscanner); +"r" STRCAT("\r", 1); yy_pop_state(yyscanner); +"t" STRCAT("\t", 1); yy_pop_state(yyscanner); +"v" STRCAT("\v", 1); yy_pop_state(yyscanner); +"\\" STRCAT("\\", 1); yy_pop_state(yyscanner); +"'" STRCAT("'", 1); yy_pop_state(yyscanner); +"\"" STRCAT("\"", 1); yy_pop_state(yyscanner); +"u"[[:digit:]aAbBcCdDeEfF]{4} { + wchar = strtoul(yytext + 1, NULL, 16); + STRCAT("", 2); + token.value[string_length - 2] = wchar/256; + token.value[string_length - 1] = wchar%256; + yy_pop_state(yyscanner); +} +. { + dmnsn_diagnostic(filename, yylineno, yycolumn, + "WARNING: unrecognised escape sequence '\\%c'", + (int)*yytext); + STRCAT(yytext, yyleng); + yy_pop_state(yyscanner); +} + +(?# Ignore whitespace) +[\b\r\t\v ]+ CALCULATE_COLUMN(); +\n ; + +(?# Fall-through) +. { + dmnsn_diagnostic(filename, yylineno, yycolumn, + "Unrecognized character '%c' (0x%X)", + (int)*yytext, (unsigned int)*yytext); + return 1; +} + +%% + +dmnsn_array * +dmnsn_tokenize(const char *filename, FILE *file) +{ + dmnsn_array *tokens = dmnsn_new_array(sizeof(dmnsn_token)); + + yyscan_t scanner; + + yylex_init(&scanner); + yyset_in(file, scanner); + + if (yylex(filename, tokens, scanner) != 0) { + dmnsn_delete_tokens(tokens); + tokens = NULL; + } + + yylex_destroy(scanner); + + return tokens; +} + +void +dmnsn_delete_tokens(dmnsn_array *tokens) +{ + dmnsn_token *token; + unsigned int i; + for (i = 0; i < dmnsn_array_size(tokens); ++i) { + token = dmnsn_array_at(tokens, i); + free(token->value); + } + dmnsn_delete_array(tokens); +} + +static void +dmnsn_print_token(FILE *file, dmnsn_token token) +{ + const char *tname; + if (token.type == DMNSN_T_LPAREN) { + tname = "\\("; + } else if (token.type == DMNSN_T_RPAREN) { + tname = "\\)"; + } else { + tname = dmnsn_token_string(token.type); + } + + if (token.value) { + fprintf(file, "(%s \"%s\")", tname, token.value); + } else { + fprintf(file, "%s", tname); + } +} + +void +dmnsn_print_token_sexpr(FILE *file, const dmnsn_array *tokens) +{ + dmnsn_token token; + unsigned int i; + + if (dmnsn_array_size(tokens) == 0) { + fprintf(file, "()"); + } else { + fprintf(file, "("); + dmnsn_array_get(tokens, 0, &token); + dmnsn_print_token(file, token); + + for (i = 1; i < dmnsn_array_size(tokens); ++i) { + fprintf(file, " "); + dmnsn_array_get(tokens, i, &token); + dmnsn_print_token(file, token); + } + + fprintf(file, ")"); + } + + fprintf(file, "\n"); +} diff --git a/dimension/tokenize.h b/dimension/tokenize.h index b9eaf04..67a386c 100644 --- a/dimension/tokenize.h +++ b/dimension/tokenize.h @@ -21,7 +21,7 @@ #define TOKENIZE_H #include "../libdimension/dimension.h" -#include "bison.h" +#include "grammar.h" typedef enum yytokentype dmnsn_token_type; -- cgit v1.2.3