00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 %{
00026
00027 #define YY_MAIN 0
00028 #define YY_NEVER_INTERACTIVE 1
00029
00030 #include <sstream>
00031 #include "lux.h"
00032 #include "api.h"
00033 #include "error.h"
00034
00035 struct ParamArray;
00036
00037 #include "luxparse.hpp"
00038
00039
00040
00041
00042
00043
00044
00045 #if defined(WIN32) && !defined(__CYGWIN__)
00046 #pragma warning ( disable: 4244 )
00047 #endif
00048
00049 struct IncludeInfo {
00050 string filename;
00051 YY_BUFFER_STATE bufState;
00052 int lineNum;
00053 };
00054 vector<IncludeInfo> includeStack;
00055
00056 extern int line_num;
00057 int str_pos;
00058
00059 void add_string_char( char c )
00060 {
00061 if (str_pos == 1023) {
00062 luxError(LUX_LIMIT, LUX_ERROR, "String is too long.");
00063 ++str_pos;
00064 } else if (str_pos < 1023) {
00065 yylval.string[str_pos++] = c;
00066 yylval.string[str_pos] = '\0';
00067 }
00068 }
00069
00070 extern void yyerror( const char *str );
00071
00072
00073 void include_push(char *filename) {
00074 if (includeStack.size() > 32)
00075 luxError(LUX_NESTING,LUX_SEVERE,"Only 32 levels of nested Include allowed in scene files.");
00076 else {
00077
00078
00079
00080 FILE *newFile = fopen(filename, "r");
00081 if (!newFile) {
00082
00083 std::stringstream ss;
00084 ss<<"Unable to open included scene file "<<filename;
00085 luxError(LUX_NOFILE,LUX_SEVERE,ss.str().c_str());
00086 } else {
00087 IncludeInfo ii;
00088 extern string current_file;
00089 ii.filename = current_file;
00090 ii.bufState = YY_CURRENT_BUFFER;
00091 ii.lineNum = line_num;
00092 includeStack.push_back(ii);
00093
00094 current_file = filename;
00095 line_num = 1;
00096
00097 yyin = newFile;
00098 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
00099 }
00100 }
00101 }
00102
00103 void include_pop(void)
00104 {
00105 extern int line_num;
00106 extern string current_file;
00107 yy_delete_buffer(YY_CURRENT_BUFFER);
00108 yy_switch_to_buffer(includeStack.back().bufState);
00109 current_file = includeStack.back().filename;
00110 line_num = includeStack.back().lineNum;
00111 includeStack.pop_back();
00112 }
00113 %}
00114 %option nounput
00115 WHITESPACE [ \t\0xa]+
00116 NUMBER [-+]?([0-9]+|(([0-9]+\.[0-9]*)|(\.[0-9]+)))([eE][-+]?[0-9]+)?
00117 IDENT [a-zA-Z_][a-zA-Z_0-9]*
00118 %x STR COMMENT INCL INCL_FILE
00119 %%
00120 Include { BEGIN(INCL); }
00121 <INCL>{WHITESPACE} ;
00122 <INCL>\" { BEGIN(INCL_FILE); }
00123 <INCL>. { luxError( LUX_SYNTAX,LUX_SEVERE,"Illegal character following Include directive" ); }
00124 <INCL_FILE>\" { BEGIN INITIAL; }
00125 <INCL_FILE>. { luxError( LUX_SYNTAX,LUX_SEVERE,"Illegal character in Include file name" ); }
00126 <INCL_FILE>[^\n\"]+ {
00127 BEGIN(INITIAL);
00128 include_push(yytext);
00129 }
00130 "#" { BEGIN COMMENT; }
00131 <COMMENT>. /* eat it up */
00132 <COMMENT>\n { line_num++; BEGIN INITIAL; }
00133 Accelerator { return ACCELERATOR; }
00134 AreaLightSource { return AREALIGHTSOURCE; }
00135 AttributeBegin { return ATTRIBUTEBEGIN; }
00136 AttributeEnd { return ATTRIBUTEEND; }
00137 Camera { return CAMERA; }
00138 ConcatTransform { return CONCATTRANSFORM; }
00139 CoordinateSystem { return COORDINATESYSTEM; }
00140 CoordSysTransform { return COORDSYSTRANSFORM; }
00141 Film { return FILM; }
00142 Identity { return IDENTITY; }
00143 LightGroup { return LIGHTGROUP; }
00144 LightSource { return LIGHTSOURCE; }
00145 LookAt { return LOOKAT; }
00146 Material { return MATERIAL; }
00147 MakeNamedMaterial { return MAKENAMEDMATERIAL; }
00148 NamedMaterial { return NAMEDMATERIAL; }
00149 ObjectBegin { return OBJECTBEGIN; }
00150 ObjectEnd { return OBJECTEND; }
00151 ObjectInstance { return OBJECTINSTANCE; }
00152 MotionInstance { return MOTIONINSTANCE; }
00153 PixelFilter { return PIXELFILTER; }
00154 ReverseOrientation { return REVERSEORIENTATION; }
00155 Rotate { return ROTATE; }
00156 Sampler { return SAMPLER; }
00157 SearchPath { return SEARCHPATH; }
00158 Scale { return SCALE; }
00159 PortalShape { return PORTALSHAPE; }
00160 Shape { return SHAPE; }
00161 SurfaceIntegrator { return SURFACEINTEGRATOR; }
00162 Texture { return TEXTURE; }
00163 TransformBegin { return TRANSFORMBEGIN; }
00164 TransformEnd { return TRANSFORMEND; }
00165 Transform { return TRANSFORM; }
00166 Translate { return TRANSLATE; }
00167 Volume { return VOLUME; }
00168 VolumeIntegrator { return VOLUMEINTEGRATOR; }
00169 WorldBegin { return WORLDBEGIN; }
00170 WorldEnd { return WORLDEND; }
00171 {WHITESPACE} /* do nothing */
00172 \r /* jromang - do nothing */
00173 \n { line_num++; }
00174 {NUMBER} {
00175 yylval.num = (float) atof(yytext);
00176 return NUM;
00177 }
00178 {IDENT} {
00179 strcpy( yylval.string, yytext );
00180 return ID;
00181 }
00182 "[" { return LBRACK; }
00183 "]" { return RBRACK; }
00184 \" { BEGIN STR; str_pos = 0; yylval.string[0] = '\0';
00185 /* I have to initialize the string as an empty one in order to handle empty strings (i.e. "") */ }
00186 <STR>\\n {add_string_char('\n');}
00187 <STR>\\t {add_string_char('\t');}
00188 <STR>\\r {add_string_char('\r');}
00189 <STR>\\b {add_string_char('\b');}
00190 <STR>\\f {add_string_char('\f');}
00191 <STR>\\\" {add_string_char('\"');}
00192 <STR>\\\\ {add_string_char('\\');}
00193 <STR>\\[0-9]{3} {
00194 int val = atoi(yytext+1);
00195 while(val > 256)
00196 val -= 256;
00197 add_string_char(val);
00198 }
00199 <STR>\\\n {line_num++;}
00200 <STR>\\. { add_string_char(yytext[1]);}
00201 <STR>\" {BEGIN INITIAL; return STRING;}
00202 <STR>. {add_string_char(yytext[0]);}
00203 <STR>\n {luxError( LUX_SYNTAX,LUX_SEVERE,"Unterminated string!");}
00204
00205 . { std::stringstream ss; ss<<"Illegal character: "<<yytext[0]; luxError( LUX_SYNTAX,LUX_SEVERE,ss.str().c_str()); }
00206 %%
00207 int yywrap(void)
00208 {
00209 if (includeStack.size() ==0) return 1;
00210 include_pop();
00211 BEGIN(INCL_FILE);
00212 return 0;
00213 }
00214