mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
egg: Make egg parser and lexer reentrant
This avoids the need for the global mutex lock and allows two egg files to be read simultaneously. Error reporting has also been improved by specifically pinpointing the offending token when an error occurs.
This commit is contained in:
parent
06484566b3
commit
91380e8718
@ -4396,7 +4396,7 @@ if GetTarget() == 'windows' and not PkgSkip("DX9"):
|
|||||||
#
|
#
|
||||||
|
|
||||||
if not PkgSkip("EGG"):
|
if not PkgSkip("EGG"):
|
||||||
OPTS=['DIR:panda/src/egg', 'BUILDING:PANDAEGG', 'ZLIB', 'BISONPREFIX_eggyy', 'FLEXDASHI', 'FLEXVERSION:2.5.9']
|
OPTS=['DIR:panda/src/egg', 'BUILDING:PANDAEGG', 'ZLIB', 'BISONPREFIX_eggyy', 'FLEXDASHI', 'FLEXVERSION:2.5.6']
|
||||||
CreateFile(GetOutputDir()+"/include/parser.h")
|
CreateFile(GetOutputDir()+"/include/parser.h")
|
||||||
TargetAdd('p3egg_parser.obj', opts=OPTS, input='parser.yxx')
|
TargetAdd('p3egg_parser.obj', opts=OPTS, input='parser.yxx')
|
||||||
TargetAdd('parser.h', input='p3egg_parser.obj', opts=['DEPENDENCYONLY'])
|
TargetAdd('parser.h', input='p3egg_parser.obj', opts=['DEPENDENCYONLY'])
|
||||||
|
@ -114,13 +114,12 @@ read(istream &in) {
|
|||||||
// set it.
|
// set it.
|
||||||
PT(EggData) data = new EggData(*this);
|
PT(EggData) data = new EggData(*this);
|
||||||
|
|
||||||
int error_count;
|
bool success;
|
||||||
{
|
{
|
||||||
LightMutexHolder holder(egg_lock);
|
EggLexerState lexer_state;
|
||||||
egg_init_parser(in, get_egg_filename(), data, data);
|
egg_init_lexer_state(lexer_state, in, get_egg_filename());
|
||||||
eggyyparse();
|
success = egg_parse(lexer_state, data, data);
|
||||||
egg_cleanup_parser();
|
egg_cleanup_lexer_state(lexer_state);
|
||||||
error_count = egg_error_count();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data->post_read();
|
data->post_read();
|
||||||
@ -128,7 +127,7 @@ read(istream &in) {
|
|||||||
steal_children(*data);
|
steal_children(*data);
|
||||||
(*this) = *data;
|
(*this) = *data;
|
||||||
|
|
||||||
return (error_count == 0);
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1094,8 +1094,8 @@ write_vertex_ref(ostream &out, int indent_level) const {
|
|||||||
* return false.
|
* return false.
|
||||||
*/
|
*/
|
||||||
bool EggGroup::
|
bool EggGroup::
|
||||||
egg_start_parse_body() {
|
egg_start_parse_body(EggLexerState &state) {
|
||||||
egg_start_group_body();
|
egg_start_group_body(state);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,7 +369,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void write_vertex_ref(std::ostream &out, int indent_level) const;
|
void write_vertex_ref(std::ostream &out, int indent_level) const;
|
||||||
virtual bool egg_start_parse_body();
|
virtual bool egg_start_parse_body(EggLexerState &state);
|
||||||
virtual void adjust_under();
|
virtual void adjust_under();
|
||||||
virtual void r_transform(const LMatrix4d &mat, const LMatrix4d &inv,
|
virtual void r_transform(const LMatrix4d &mat, const LMatrix4d &inv,
|
||||||
CoordinateSystem to_cs);
|
CoordinateSystem to_cs);
|
||||||
|
@ -229,19 +229,13 @@ parse_egg(const std::string &egg_syntax) {
|
|||||||
|
|
||||||
std::istringstream in(egg_syntax);
|
std::istringstream in(egg_syntax);
|
||||||
|
|
||||||
LightMutexHolder holder(egg_lock);
|
EggLexerState lexer_state;
|
||||||
|
egg_init_lexer_state(lexer_state, in, "");
|
||||||
egg_init_parser(in, "", this, group);
|
if (!egg_start_parse_body(lexer_state)) {
|
||||||
|
|
||||||
if (!egg_start_parse_body()) {
|
|
||||||
egg_cleanup_parser();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
eggyyparse();
|
return egg_parse(lexer_state, this, group);
|
||||||
egg_cleanup_parser();
|
|
||||||
|
|
||||||
return (egg_error_count() == 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
@ -287,7 +281,7 @@ test_under_integrity() const {
|
|||||||
* return false.
|
* return false.
|
||||||
*/
|
*/
|
||||||
bool EggNode::
|
bool EggNode::
|
||||||
egg_start_parse_body() {
|
egg_start_parse_body(EggLexerState &state) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,8 @@ class EggGroupNode;
|
|||||||
class EggRenderMode;
|
class EggRenderMode;
|
||||||
class EggTextureCollection;
|
class EggTextureCollection;
|
||||||
|
|
||||||
|
struct EggLexerState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A base class for things that may be directly added into the egg hierarchy.
|
* A base class for things that may be directly added into the egg hierarchy.
|
||||||
* This includes groups, joints, polygons, vertex pools, etc., but does not
|
* This includes groups, joints, polygons, vertex pools, etc., but does not
|
||||||
@ -100,7 +102,7 @@ protected:
|
|||||||
UF_local_coord = 0x004,
|
UF_local_coord = 0x004,
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual bool egg_start_parse_body();
|
virtual bool egg_start_parse_body(EggLexerState &state);
|
||||||
|
|
||||||
virtual void update_under(int depth_offset);
|
virtual void update_under(int depth_offset);
|
||||||
virtual void adjust_under();
|
virtual void adjust_under();
|
||||||
|
@ -905,8 +905,8 @@ write_body(std::ostream &out, int indent_level) const {
|
|||||||
* return false.
|
* return false.
|
||||||
*/
|
*/
|
||||||
bool EggPrimitive::
|
bool EggPrimitive::
|
||||||
egg_start_parse_body() {
|
egg_start_parse_body(EggLexerState &state) {
|
||||||
egg_start_primitive_body();
|
egg_start_primitive_body(state);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,7 +211,7 @@ protected:
|
|||||||
protected:
|
protected:
|
||||||
void write_body(std::ostream &out, int indent_level) const;
|
void write_body(std::ostream &out, int indent_level) const;
|
||||||
|
|
||||||
virtual bool egg_start_parse_body();
|
virtual bool egg_start_parse_body(EggLexerState &state);
|
||||||
virtual void r_transform(const LMatrix4d &mat, const LMatrix4d &inv,
|
virtual void r_transform(const LMatrix4d &mat, const LMatrix4d &inv,
|
||||||
CoordinateSystem to_cs);
|
CoordinateSystem to_cs);
|
||||||
virtual void r_flatten_transforms();
|
virtual void r_flatten_transforms();
|
||||||
|
@ -1063,8 +1063,8 @@ as_transform() {
|
|||||||
* return false.
|
* return false.
|
||||||
*/
|
*/
|
||||||
bool EggTexture::
|
bool EggTexture::
|
||||||
egg_start_parse_body() {
|
egg_start_parse_body(EggLexerState &state) {
|
||||||
egg_start_texture_body();
|
egg_start_texture_body(state);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,7 +365,7 @@ public:
|
|||||||
virtual EggTransform *as_transform();
|
virtual EggTransform *as_transform();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool egg_start_parse_body();
|
virtual bool egg_start_parse_body(EggLexerState &state);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef pset<EggTexture *> MultiTextures;
|
typedef pset<EggTexture *> MultiTextures;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -4,6 +4,10 @@
|
|||||||
* @date 1999-01-16
|
* @date 1999-01-16
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
%option reentrant bison-bridge bison-locations
|
||||||
|
%option noyywrap
|
||||||
|
%option case-insensitive
|
||||||
|
|
||||||
%{
|
%{
|
||||||
#include "pandabase.h"
|
#include "pandabase.h"
|
||||||
#include "lexerDefs.h"
|
#include "lexerDefs.h"
|
||||||
@ -18,182 +22,156 @@
|
|||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
using std::istream;
|
// These are declared by flex.
|
||||||
using std::ostream;
|
static int yyinput(yyscan_t yyscanner);
|
||||||
using std::string;
|
static EggLexerState *eggyyget_extra(yyscan_t scanner);
|
||||||
|
|
||||||
extern "C" int eggyywrap(void); // declared below.
|
|
||||||
|
|
||||||
static int yyinput(void); // declared by flex.
|
|
||||||
|
|
||||||
int eggyylex_destroy(void);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Static variables
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// This mutex protects all of these global variables.
|
|
||||||
LightMutex egg_lock;
|
|
||||||
|
|
||||||
// We'll increment line_number and col_number as we parse the file, so
|
|
||||||
// that we can report the position of an error.
|
|
||||||
static int line_number = 0;
|
|
||||||
static int col_number = 0;
|
|
||||||
|
|
||||||
// current_line holds as much of the current line as will fit. Its
|
|
||||||
// only purpose is for printing it out to report an error to the user.
|
|
||||||
static const int max_error_width = 1024;
|
|
||||||
static char current_line[max_error_width + 1];
|
|
||||||
|
|
||||||
static int error_count = 0;
|
|
||||||
static int warning_count = 0;
|
|
||||||
|
|
||||||
// This is the pointer to the current input stream.
|
|
||||||
static istream *input_p = nullptr;
|
|
||||||
|
|
||||||
// This is the name of the egg file we're parsing. We keep it so we
|
|
||||||
// can print it out for error messages.
|
|
||||||
static string egg_filename;
|
|
||||||
|
|
||||||
// This is the initial token state returned by the lexer. It allows
|
|
||||||
// the yacc grammar to start from initial points.
|
|
||||||
static int initial_token;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Defining the interface to the lexer.
|
// Defining the interface to the lexer.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void
|
void
|
||||||
egg_init_lexer(istream &in, const string &filename) {
|
egg_init_lexer_state(EggLexerState &state, std::istream &in, const std::string &filename) {
|
||||||
input_p = ∈
|
state._error_count = 0;
|
||||||
egg_filename = filename;
|
state._warning_count = 0;
|
||||||
line_number = 0;
|
state._input_p = ∈
|
||||||
col_number = 0;
|
state._egg_filename = filename;
|
||||||
error_count = 0;
|
state._initial_token = START_EGG;
|
||||||
warning_count = 0;
|
|
||||||
initial_token = START_EGG;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
egg_cleanup_lexer() {
|
egg_cleanup_lexer_state(EggLexerState &state) {
|
||||||
// Reset the lexer state.
|
state._input_p = nullptr;
|
||||||
yylex_destroy();
|
state._egg_filename.clear();
|
||||||
|
|
||||||
input_p = nullptr;
|
|
||||||
egg_filename.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
egg_start_group_body() {
|
egg_start_group_body(EggLexerState &state) {
|
||||||
/* Set the initial state to begin within a group_body context,
|
/* Set the initial state to begin within a group_body context,
|
||||||
instead of at the beginning of the egg file. */
|
instead of at the beginning of the egg file. */
|
||||||
initial_token = START_GROUP_BODY;
|
state._initial_token = START_GROUP_BODY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
egg_start_texture_body() {
|
egg_start_texture_body(EggLexerState &state) {
|
||||||
initial_token = START_TEXTURE_BODY;
|
state._initial_token = START_TEXTURE_BODY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
egg_start_primitive_body() {
|
egg_start_primitive_body(EggLexerState &state) {
|
||||||
initial_token = START_PRIMITIVE_BODY;
|
state._initial_token = START_PRIMITIVE_BODY;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
egg_error_count() {
|
|
||||||
return error_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
egg_warning_count() {
|
|
||||||
return warning_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Internal support functions.
|
// Internal support functions.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
int
|
|
||||||
eggyywrap(void) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
eggyyerror(const string &msg) {
|
eggyyerror(YYLTYPE *loc, yyscan_t scanner, const std::string &msg) {
|
||||||
|
EggLexerState *lexer_state = eggyyget_extra(scanner);
|
||||||
|
|
||||||
if (egg_cat.is_error()) {
|
if (egg_cat.is_error()) {
|
||||||
ostream &out = egg_cat.error(false);
|
std::ostream &out = egg_cat.error(false);
|
||||||
|
|
||||||
out << "\nError";
|
out << "\nError";
|
||||||
if (!egg_filename.empty()) {
|
if (!lexer_state->_egg_filename.empty()) {
|
||||||
out << " in " << egg_filename;
|
out << " in " << lexer_state->_egg_filename;
|
||||||
}
|
}
|
||||||
|
if (loc != nullptr) {
|
||||||
out
|
out
|
||||||
<< " at line " << line_number << ", column " << col_number << ":\n"
|
<< " at line " << loc->first_line << ", column " << loc->first_column << ":\n"
|
||||||
<< std::setiosflags(Notify::get_literal_flag())
|
<< std::setiosflags(Notify::get_literal_flag())
|
||||||
<< current_line << "\n";
|
<< lexer_state->_current_line << "\n";
|
||||||
indent(out, col_number-1)
|
indent(out, loc->first_column - 1)
|
||||||
<< "^\n" << msg << "\n\n"
|
<< "^";
|
||||||
|
|
||||||
|
int last_column;
|
||||||
|
if (loc->first_line == loc->last_line) {
|
||||||
|
last_column = loc->last_column;
|
||||||
|
} else {
|
||||||
|
last_column = strlen(lexer_state->_current_line);
|
||||||
|
}
|
||||||
|
for (int i = loc->first_column; i < last_column; ++i) {
|
||||||
|
out.put('~');
|
||||||
|
}
|
||||||
|
|
||||||
|
out
|
||||||
|
<< "\n" << msg << "\n\n"
|
||||||
<< std::resetiosflags(Notify::get_literal_flag()) << std::flush;
|
<< std::resetiosflags(Notify::get_literal_flag()) << std::flush;
|
||||||
}
|
}
|
||||||
error_count++;
|
else {
|
||||||
|
out << ":\n" << msg << "\n\n" << std::flush;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lexer_state->_error_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
eggyyerror(std::ostringstream &strm) {
|
eggyywarning(YYLTYPE *loc, yyscan_t scanner, const std::string &msg) {
|
||||||
string s = strm.str();
|
EggLexerState *lexer_state = eggyyget_extra(scanner);
|
||||||
eggyyerror(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
eggyywarning(const string &msg) {
|
|
||||||
if (egg_cat.is_warning()) {
|
if (egg_cat.is_warning()) {
|
||||||
ostream &out = egg_cat.warning(false);
|
std::ostream &out = egg_cat.warning(false);
|
||||||
|
|
||||||
out << "\nWarning";
|
out << "\nWarning";
|
||||||
if (!egg_filename.empty()) {
|
if (!lexer_state->_egg_filename.empty()) {
|
||||||
out << " in " << egg_filename;
|
out << " in " << lexer_state->_egg_filename;
|
||||||
}
|
}
|
||||||
|
if (loc != nullptr) {
|
||||||
out
|
out
|
||||||
<< " at line " << line_number << ", column " << col_number << ":\n"
|
<< " at line " << loc->first_line << ", column " << loc->first_column << ":\n"
|
||||||
<< std::setiosflags(Notify::get_literal_flag())
|
<< std::setiosflags(Notify::get_literal_flag())
|
||||||
<< current_line << "\n";
|
<< lexer_state->_current_line << "\n";
|
||||||
indent(out, col_number-1)
|
indent(out, loc->first_column - 1)
|
||||||
<< "^\n" << msg << "\n\n"
|
<< "^";
|
||||||
|
|
||||||
|
int last_column;
|
||||||
|
if (loc->first_line == loc->last_line) {
|
||||||
|
last_column = loc->last_column;
|
||||||
|
} else {
|
||||||
|
last_column = strlen(lexer_state->_current_line);
|
||||||
|
}
|
||||||
|
for (int i = loc->first_column; i < last_column; ++i) {
|
||||||
|
out.put('~');
|
||||||
|
}
|
||||||
|
|
||||||
|
out
|
||||||
|
<< "\n" << msg << "\n\n"
|
||||||
<< std::resetiosflags(Notify::get_literal_flag()) << std::flush;
|
<< std::resetiosflags(Notify::get_literal_flag()) << std::flush;
|
||||||
}
|
}
|
||||||
warning_count++;
|
else {
|
||||||
}
|
out << ":\n" << msg << "\n\n" << std::flush;
|
||||||
|
}
|
||||||
void
|
}
|
||||||
eggyywarning(std::ostringstream &strm) {
|
lexer_state->_warning_count++;
|
||||||
string s = strm.str();
|
|
||||||
eggyywarning(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now define a function to take input from an istream instead of a
|
// Now define a function to take input from an istream instead of a
|
||||||
// stdio FILE pointer. This is flex-specific.
|
// stdio FILE pointer. This is flex-specific.
|
||||||
static void
|
static void
|
||||||
input_chars(char *buffer, int &result, int max_size) {
|
input_chars(YYLTYPE *yylloc, yyscan_t yyscanner, char *buffer, int &result, int max_size) {
|
||||||
nassertv(input_p != nullptr);
|
EggLexerState &state = *yyget_extra(yyscanner);
|
||||||
if (*input_p) {
|
|
||||||
input_p->read(buffer, max_size);
|
|
||||||
result = input_p->gcount();
|
|
||||||
|
|
||||||
if (line_number == 0) {
|
nassertv(state._input_p != nullptr);
|
||||||
|
if (*state._input_p) {
|
||||||
|
state._input_p->read(buffer, max_size);
|
||||||
|
result = state._input_p->gcount();
|
||||||
|
|
||||||
|
if (yylloc->last_line == 0) {
|
||||||
// This is a special case. If we are reading the very first bit
|
// This is a special case. If we are reading the very first bit
|
||||||
// from the stream, copy it into the current_line array. This
|
// from the stream, copy it into the _current_line array. This
|
||||||
// is because the \n.* rule below, which fills current_line
|
// is because the \n.* rule below, which fills _current_line
|
||||||
// normally, doesn't catch the first line.
|
// normally, doesn't catch the first line.
|
||||||
int length = std::min(max_error_width, result);
|
size_t length = std::min(egg_max_error_width, (size_t)result);
|
||||||
strncpy(current_line, buffer, length);
|
strncpy(state._current_line, buffer, length);
|
||||||
current_line[length] = '\0';
|
state._current_line[length] = '\0';
|
||||||
line_number++;
|
yylloc->first_line = 1;
|
||||||
col_number = 0;
|
yylloc->last_line = 1;
|
||||||
|
yylloc->first_column = 0;
|
||||||
|
yylloc->last_column = 0;
|
||||||
|
|
||||||
// Truncate it at the newline.
|
// Truncate it at the newline.
|
||||||
char *end = strchr(current_line, '\n');
|
char *end = strchr(state._current_line, '\n');
|
||||||
if (end != nullptr) {
|
if (end != nullptr) {
|
||||||
*end = '\0';
|
*end = '\0';
|
||||||
}
|
}
|
||||||
@ -211,7 +189,7 @@ input_chars(char *buffer, int &result, int max_size) {
|
|||||||
// with a different type for result.
|
// with a different type for result.
|
||||||
#define YY_INPUT(buffer, result, max_size) { \
|
#define YY_INPUT(buffer, result, max_size) { \
|
||||||
int int_result = 0; \
|
int int_result = 0; \
|
||||||
input_chars((buffer), int_result, (max_size)); \
|
input_chars(yylloc, yyscanner, (buffer), int_result, (max_size)); \
|
||||||
(result) = int_result; \
|
(result) = int_result; \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,8 +197,8 @@ input_chars(char *buffer, int &result, int max_size) {
|
|||||||
// supplied line and column numbers as appropriate. A convenience
|
// supplied line and column numbers as appropriate. A convenience
|
||||||
// function for the scanning functions below.
|
// function for the scanning functions below.
|
||||||
static int
|
static int
|
||||||
read_char(int &line, int &col) {
|
read_char(yyscan_t yyscanner, int &line, int &col) {
|
||||||
int c = yyinput();
|
int c = yyinput(yyscanner);
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
line++;
|
line++;
|
||||||
col = 0;
|
col = 0;
|
||||||
@ -232,78 +210,56 @@ read_char(int &line, int &col) {
|
|||||||
|
|
||||||
// scan_quoted_string reads a string delimited by quotation marks and
|
// scan_quoted_string reads a string delimited by quotation marks and
|
||||||
// returns it.
|
// returns it.
|
||||||
static string
|
static std::string
|
||||||
scan_quoted_string() {
|
scan_quoted_string(YYLTYPE *yylloc, yyscan_t yyscanner) {
|
||||||
string result;
|
std::string result;
|
||||||
|
|
||||||
// We don't touch the current line number and column number during
|
|
||||||
// scanning, so that if we detect an error while scanning the string
|
|
||||||
// (e.g. an unterminated string), we'll report the error as
|
|
||||||
// occurring at the start of the string, not at the end--somewhat
|
|
||||||
// more convenient for the user.
|
|
||||||
|
|
||||||
// Instead of adjusting the global line_number and col_number
|
|
||||||
// variables, we'll operate on our own local variables for the
|
|
||||||
// interim.
|
|
||||||
int line = line_number;
|
|
||||||
int col = col_number;
|
|
||||||
|
|
||||||
int c;
|
int c;
|
||||||
c = read_char(line, col);
|
c = read_char(yyscanner, yylloc->last_line, yylloc->last_column);
|
||||||
while (c != '"' && c != 0 && c != EOF) {
|
while (c != '"' && c != 0 && c != EOF) {
|
||||||
result += c;
|
result += c;
|
||||||
c = read_char(line, col);
|
c = read_char(yyscanner, yylloc->last_line, yylloc->last_column);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == 0 || c == EOF) {
|
if (c == 0 || c == EOF) {
|
||||||
eggyyerror("This quotation mark is unterminated.");
|
eggyyerror(yylloc, yyscanner, "This quotation mark is unterminated.");
|
||||||
}
|
}
|
||||||
|
|
||||||
line_number = line;
|
|
||||||
col_number = col;
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// eat_c_comment scans past all characters up until the first */
|
// eat_c_comment scans past all characters up until the first */
|
||||||
// encountered.
|
// encountered.
|
||||||
static void
|
static void
|
||||||
eat_c_comment() {
|
eat_c_comment(YYLTYPE *yylloc, yyscan_t yyscanner) {
|
||||||
// As above, we'll operate on our own local copies of line_number
|
|
||||||
// and col_number within this function.
|
|
||||||
|
|
||||||
int line = line_number;
|
|
||||||
int col = col_number;
|
|
||||||
|
|
||||||
int c, last_c;
|
int c, last_c;
|
||||||
|
|
||||||
last_c = '\0';
|
last_c = '\0';
|
||||||
c = read_char(line, col);
|
c = read_char(yyscanner, yylloc->last_line, yylloc->last_column);
|
||||||
while (c != 0 && c != EOF && !(last_c == '*' && c == '/')) {
|
while (c != 0 && c != EOF && !(last_c == '*' && c == '/')) {
|
||||||
if (last_c == '/' && c == '*') {
|
if (last_c == '/' && c == '*') {
|
||||||
std::ostringstream errmsg;
|
std::ostringstream errmsg;
|
||||||
errmsg << "This comment contains a nested /* symbol at line "
|
errmsg << "This comment contains a nested /* symbol at line "
|
||||||
<< line << ", column " << col-1 << "--possibly unclosed?"
|
<< yylloc->last_line << ", column " << yylloc->last_column - 1
|
||||||
<< std::ends;
|
<< "--possibly unclosed?" << std::ends;
|
||||||
eggyywarning(errmsg);
|
eggyywarning(yylloc, yyscanner, errmsg.str());
|
||||||
}
|
}
|
||||||
last_c = c;
|
last_c = c;
|
||||||
c = read_char(line, col);
|
c = read_char(yyscanner, yylloc->last_line, yylloc->last_column);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == 0 || c == EOF) {
|
if (c == 0 || c == EOF) {
|
||||||
eggyyerror("This comment marker is unclosed.");
|
eggyyerror(yylloc, yyscanner, "This comment marker is unclosed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
line_number = line;
|
|
||||||
col_number = col;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// accept() is called below as each piece is pulled off and
|
// accept() is called below as each piece is pulled off and
|
||||||
// accepted by the lexer; it increments the current column number.
|
// accepted by the lexer; it increments the current column number.
|
||||||
INLINE void accept() {
|
#define accept() { \
|
||||||
col_number += yyleng;
|
yylloc->first_line = yylloc->last_line; \
|
||||||
|
yylloc->first_column = yylloc->last_column + 1; \
|
||||||
|
yylloc->last_column += yyleng; \
|
||||||
}
|
}
|
||||||
|
|
||||||
%}
|
%}
|
||||||
@ -315,9 +271,9 @@ NUMERIC ([+-]?(([0-9]+[.]?)|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
|||||||
%%
|
%%
|
||||||
|
|
||||||
%{
|
%{
|
||||||
if (initial_token != 0) {
|
if (yyextra->_initial_token != 0) {
|
||||||
int t = initial_token;
|
int t = yyextra->_initial_token;
|
||||||
initial_token = 0;
|
yyextra->_initial_token = 0;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
@ -326,10 +282,13 @@ NUMERIC ([+-]?(([0-9]+[.]?)|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
|||||||
// New line. Save a copy of the line so we can print it out for the
|
// New line. Save a copy of the line so we can print it out for the
|
||||||
// benefit of the user in case we get an error.
|
// benefit of the user in case we get an error.
|
||||||
|
|
||||||
strncpy(current_line, yytext+1, max_error_width);
|
strncpy(yyextra->_current_line, yytext+1, egg_max_error_width);
|
||||||
current_line[max_error_width] = '\0';
|
yyextra->_current_line[egg_max_error_width] = '\0';
|
||||||
line_number++;
|
|
||||||
col_number=0;
|
yylloc->first_line++;
|
||||||
|
yylloc->last_line++;
|
||||||
|
yylloc->first_column = 0;
|
||||||
|
yylloc->last_column = 0;
|
||||||
|
|
||||||
// Return the whole line to the lexer, except the newline character,
|
// Return the whole line to the lexer, except the newline character,
|
||||||
// which we eat.
|
// which we eat.
|
||||||
@ -349,13 +308,13 @@ NUMERIC ([+-]?(([0-9]+[.]?)|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
|||||||
"/*" {
|
"/*" {
|
||||||
// Eat C-style comments.
|
// Eat C-style comments.
|
||||||
accept();
|
accept();
|
||||||
eat_c_comment();
|
eat_c_comment(yylloc, yyscanner);
|
||||||
}
|
}
|
||||||
|
|
||||||
[{}] {
|
[{}] {
|
||||||
// Send curly braces as themselves.
|
// Send curly braces as themselves.
|
||||||
accept();
|
accept();
|
||||||
return eggyytext[0];
|
return yytext[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -706,65 +665,65 @@ NUMERIC ([+-]?(([0-9]+[.]?)|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
|||||||
{NUMERIC} {
|
{NUMERIC} {
|
||||||
// An integer or floating-point number.
|
// An integer or floating-point number.
|
||||||
accept();
|
accept();
|
||||||
eggyylval._number = patof(eggyytext);
|
yylval->_number = patof(yytext);
|
||||||
eggyylval._string = yytext;
|
yylval->_string = yytext;
|
||||||
return EGG_NUMBER;
|
return EGG_NUMBER;
|
||||||
}
|
}
|
||||||
|
|
||||||
{HEX} {
|
{HEX} {
|
||||||
// A hexadecimal integer number.
|
// A hexadecimal integer number.
|
||||||
accept();
|
accept();
|
||||||
eggyylval._ulong = strtoul(yytext+2, nullptr, 16);
|
yylval->_ulong = strtoul(yytext+2, nullptr, 16);
|
||||||
eggyylval._string = yytext;
|
yylval->_string = yytext;
|
||||||
return EGG_ULONG;
|
return EGG_ULONG;
|
||||||
}
|
}
|
||||||
|
|
||||||
{BINARY} {
|
{BINARY} {
|
||||||
// A binary integer number.
|
// A binary integer number.
|
||||||
accept();
|
accept();
|
||||||
eggyylval._ulong = strtoul(yytext+2, nullptr, 2);
|
yylval->_ulong = strtoul(yytext+2, nullptr, 2);
|
||||||
eggyylval._string = yytext;
|
yylval->_string = yytext;
|
||||||
return EGG_ULONG;
|
return EGG_ULONG;
|
||||||
}
|
}
|
||||||
|
|
||||||
"nan"{HEX} {
|
"nan"{HEX} {
|
||||||
// not-a-number. These sometimes show up in egg files accidentally.
|
// not-a-number. These sometimes show up in egg files accidentally.
|
||||||
accept();
|
accept();
|
||||||
memset(&eggyylval._number, 0, sizeof(eggyylval._number));
|
memset(&yylval->_number, 0, sizeof(yylval->_number));
|
||||||
*(unsigned long *)&eggyylval._number = strtoul(yytext+3, nullptr, 0);
|
*(unsigned long *)&yylval->_number = strtoul(yytext+3, nullptr, 0);
|
||||||
eggyylval._string = yytext;
|
yylval->_string = yytext;
|
||||||
return EGG_NUMBER;
|
return EGG_NUMBER;
|
||||||
}
|
}
|
||||||
|
|
||||||
"inf" {
|
"inf" {
|
||||||
// infinity. As above.
|
// infinity. As above.
|
||||||
accept();
|
accept();
|
||||||
eggyylval._number = HUGE_VAL;
|
yylval->_number = HUGE_VAL;
|
||||||
eggyylval._string = yytext;
|
yylval->_string = yytext;
|
||||||
return EGG_NUMBER;
|
return EGG_NUMBER;
|
||||||
}
|
}
|
||||||
|
|
||||||
"-inf" {
|
"-inf" {
|
||||||
// minus infinity. As above.
|
// minus infinity. As above.
|
||||||
accept();
|
accept();
|
||||||
eggyylval._number = -HUGE_VAL;
|
yylval->_number = -HUGE_VAL;
|
||||||
eggyylval._string = yytext;
|
yylval->_string = yytext;
|
||||||
return EGG_NUMBER;
|
return EGG_NUMBER;
|
||||||
}
|
}
|
||||||
|
|
||||||
"1.#inf" {
|
"1.#inf" {
|
||||||
// infinity, on Win32. As above.
|
// infinity, on Win32. As above.
|
||||||
accept();
|
accept();
|
||||||
eggyylval._number = HUGE_VAL;
|
yylval->_number = HUGE_VAL;
|
||||||
eggyylval._string = yytext;
|
yylval->_string = yytext;
|
||||||
return EGG_NUMBER;
|
return EGG_NUMBER;
|
||||||
}
|
}
|
||||||
|
|
||||||
"-1.#inf" {
|
"-1.#inf" {
|
||||||
// minus infinity, on Win32. As above.
|
// minus infinity, on Win32. As above.
|
||||||
accept();
|
accept();
|
||||||
eggyylval._number = -HUGE_VAL;
|
yylval->_number = -HUGE_VAL;
|
||||||
eggyylval._string = yytext;
|
yylval->_string = yytext;
|
||||||
return EGG_NUMBER;
|
return EGG_NUMBER;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -772,13 +731,13 @@ NUMERIC ([+-]?(([0-9]+[.]?)|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
|||||||
["] {
|
["] {
|
||||||
// Quoted string.
|
// Quoted string.
|
||||||
accept();
|
accept();
|
||||||
eggyylval._string = scan_quoted_string();
|
yylval->_string = scan_quoted_string(yylloc, yyscanner);
|
||||||
return EGG_STRING;
|
return EGG_STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
[^ \t\n\r{}"]+ {
|
[^ \t\n\r{}"]+ {
|
||||||
// Unquoted string.
|
// Unquoted string.
|
||||||
accept();
|
accept();
|
||||||
eggyylval._string = yytext;
|
yylval->_string = yytext;
|
||||||
return EGG_STRING;
|
return EGG_STRING;
|
||||||
}
|
}
|
||||||
|
@ -15,26 +15,56 @@
|
|||||||
#define LEXER_H
|
#define LEXER_H
|
||||||
|
|
||||||
#include "pandabase.h"
|
#include "pandabase.h"
|
||||||
|
#include "parserDefs.h"
|
||||||
#include "typedef.h"
|
#include "typedef.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
void egg_init_lexer(std::istream &in, const std::string &filename);
|
typedef void *yyscan_t;
|
||||||
void egg_cleanup_lexer();
|
struct EggLexerState;
|
||||||
void egg_start_group_body();
|
struct EggParserState;
|
||||||
void egg_start_texture_body();
|
struct EggTokenType;
|
||||||
void egg_start_primitive_body();
|
struct EggLocType;
|
||||||
int egg_error_count();
|
|
||||||
int egg_warning_count();
|
|
||||||
|
|
||||||
void eggyyerror(const std::string &msg);
|
void egg_init_lexer_state(EggLexerState &state, std::istream &in, const std::string &filename);
|
||||||
void eggyyerror(std::ostringstream &strm);
|
void egg_cleanup_lexer_state(EggLexerState &state);
|
||||||
|
|
||||||
void eggyywarning(const std::string &msg);
|
void egg_start_group_body(EggLexerState &state);
|
||||||
void eggyywarning(std::ostringstream &strm);
|
void egg_start_texture_body(EggLexerState &state);
|
||||||
|
void egg_start_primitive_body(EggLexerState &state);
|
||||||
|
|
||||||
int eggyylex();
|
// These functions are declared by flex.
|
||||||
|
int eggyylex_init_extra(EggLexerState *state, yyscan_t *scanner);
|
||||||
|
int eggyylex_destroy(yyscan_t scanner);
|
||||||
|
|
||||||
|
void eggyyerror(EggLocType *loc, yyscan_t scanner, const std::string &msg);
|
||||||
|
void eggyywarning(EggLocType *loc, yyscan_t scanner, const std::string &msg);
|
||||||
|
|
||||||
|
int eggyylex(EggTokenType *yylval_param, EggLocType *yylloc_param, yyscan_t yyscanner);
|
||||||
|
|
||||||
|
static const size_t egg_max_error_width = 1024;
|
||||||
|
|
||||||
|
struct EggLexerState {
|
||||||
|
// current_line holds as much of the current line as will fit. Its
|
||||||
|
// only purpose is for printing it out to report an error to the user.
|
||||||
|
char _current_line[egg_max_error_width + 1];
|
||||||
|
|
||||||
|
int _error_count = 0;
|
||||||
|
int _warning_count = 0;
|
||||||
|
|
||||||
|
// This is the pointer to the current input stream.
|
||||||
|
std::istream *_input_p = nullptr;
|
||||||
|
|
||||||
|
// This is the name of the egg file we're parsing. We keep it so we
|
||||||
|
// can print it out for error messages.
|
||||||
|
std::string _egg_filename;
|
||||||
|
|
||||||
|
// This is the initial token state returned by the lexer. It allows
|
||||||
|
// the yacc grammar to start from initial points.
|
||||||
|
int _initial_token = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define YY_EXTRA_TYPE EggLexerState *
|
||||||
|
|
||||||
// always read from files
|
// always read from files
|
||||||
#define YY_NEVER_INTERACTIVE 1
|
#define YY_NEVER_INTERACTIVE 1
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,9 @@
|
|||||||
/* A Bison parser, made by GNU Bison 3.2.2. */
|
/* A Bison parser, made by GNU Bison 3.7.2. */
|
||||||
|
|
||||||
/* Bison interface for Yacc-like parsers in C
|
/* Bison interface for Yacc-like parsers in C
|
||||||
|
|
||||||
Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc.
|
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,
|
||||||
|
Inc.
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -30,8 +31,9 @@
|
|||||||
This special exception was added by the Free Software Foundation in
|
This special exception was added by the Free Software Foundation in
|
||||||
version 2.2 of Bison. */
|
version 2.2 of Bison. */
|
||||||
|
|
||||||
/* Undocumented macros, especially those whose name start with YY_,
|
/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
|
||||||
are private implementation details. Do not rely on them. */
|
especially those whose name start with YY_ or yy_. They are
|
||||||
|
private implementation details that can be changed or removed. */
|
||||||
|
|
||||||
#ifndef YY_EGGYY_BUILT_TMP_PARSER_YXX_H_INCLUDED
|
#ifndef YY_EGGYY_BUILT_TMP_PARSER_YXX_H_INCLUDED
|
||||||
# define YY_EGGYY_BUILT_TMP_PARSER_YXX_H_INCLUDED
|
# define YY_EGGYY_BUILT_TMP_PARSER_YXX_H_INCLUDED
|
||||||
@ -43,103 +45,111 @@
|
|||||||
extern int eggyydebug;
|
extern int eggyydebug;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Token type. */
|
/* Token kinds. */
|
||||||
#ifndef YYTOKENTYPE
|
#ifndef YYTOKENTYPE
|
||||||
# define YYTOKENTYPE
|
# define YYTOKENTYPE
|
||||||
enum yytokentype
|
enum yytokentype
|
||||||
{
|
{
|
||||||
EGG_NUMBER = 258,
|
YYEMPTY = -2,
|
||||||
EGG_ULONG = 259,
|
YYEOF = 0, /* "end of file" */
|
||||||
EGG_STRING = 260,
|
YYerror = 256, /* error */
|
||||||
ANIMPRELOAD = 261,
|
YYUNDEF = 257, /* "invalid token" */
|
||||||
BEZIERCURVE = 262,
|
EGG_NUMBER = 258, /* EGG_NUMBER */
|
||||||
BFACE = 263,
|
EGG_ULONG = 259, /* EGG_ULONG */
|
||||||
BILLBOARD = 264,
|
EGG_STRING = 260, /* EGG_STRING */
|
||||||
BILLBOARDCENTER = 265,
|
ANIMPRELOAD = 261, /* ANIMPRELOAD */
|
||||||
BINORMAL = 266,
|
BEZIERCURVE = 262, /* BEZIERCURVE */
|
||||||
BUNDLE = 267,
|
BFACE = 263, /* BFACE */
|
||||||
CLOSED = 268,
|
BILLBOARD = 264, /* BILLBOARD */
|
||||||
COLLIDE = 269,
|
BILLBOARDCENTER = 265, /* BILLBOARDCENTER */
|
||||||
COMMENT = 270,
|
BINORMAL = 266, /* BINORMAL */
|
||||||
COMPONENT = 271,
|
BUNDLE = 267, /* BUNDLE */
|
||||||
COORDSYSTEM = 272,
|
CLOSED = 268, /* CLOSED */
|
||||||
CV = 273,
|
COLLIDE = 269, /* COLLIDE */
|
||||||
DART = 274,
|
COMMENT = 270, /* COMMENT */
|
||||||
DNORMAL = 275,
|
COMPONENT = 271, /* COMPONENT */
|
||||||
DRGBA = 276,
|
COORDSYSTEM = 272, /* COORDSYSTEM */
|
||||||
DUV = 277,
|
CV = 273, /* CV */
|
||||||
DXYZ = 278,
|
DART = 274, /* DART */
|
||||||
DCS = 279,
|
DNORMAL = 275, /* DNORMAL */
|
||||||
DISTANCE = 280,
|
DRGBA = 276, /* DRGBA */
|
||||||
DTREF = 281,
|
DUV = 277, /* DUV */
|
||||||
DYNAMICVERTEXPOOL = 282,
|
DXYZ = 278, /* DXYZ */
|
||||||
EXTERNAL_FILE = 283,
|
DCS = 279, /* DCS */
|
||||||
GROUP = 284,
|
DISTANCE = 280, /* DISTANCE */
|
||||||
DEFAULTPOSE = 285,
|
DTREF = 281, /* DTREF */
|
||||||
JOINT = 286,
|
DYNAMICVERTEXPOOL = 282, /* DYNAMICVERTEXPOOL */
|
||||||
KNOTS = 287,
|
EXTERNAL_FILE = 283, /* EXTERNAL_FILE */
|
||||||
INCLUDE = 288,
|
GROUP = 284, /* GROUP */
|
||||||
INSTANCE = 289,
|
DEFAULTPOSE = 285, /* DEFAULTPOSE */
|
||||||
LINE = 290,
|
JOINT = 286, /* JOINT */
|
||||||
LOOP = 291,
|
KNOTS = 287, /* KNOTS */
|
||||||
MATERIAL = 292,
|
INCLUDE = 288, /* INCLUDE */
|
||||||
MATRIX3 = 293,
|
INSTANCE = 289, /* INSTANCE */
|
||||||
MATRIX4 = 294,
|
LINE = 290, /* LINE */
|
||||||
MODEL = 295,
|
LOOP = 291, /* LOOP */
|
||||||
MREF = 296,
|
MATERIAL = 292, /* MATERIAL */
|
||||||
NORMAL = 297,
|
MATRIX3 = 293, /* MATRIX3 */
|
||||||
NURBSCURVE = 298,
|
MATRIX4 = 294, /* MATRIX4 */
|
||||||
NURBSSURFACE = 299,
|
MODEL = 295, /* MODEL */
|
||||||
OBJECTTYPE = 300,
|
MREF = 296, /* MREF */
|
||||||
ORDER = 301,
|
NORMAL = 297, /* NORMAL */
|
||||||
OUTTANGENT = 302,
|
NURBSCURVE = 298, /* NURBSCURVE */
|
||||||
PATCH = 303,
|
NURBSSURFACE = 299, /* NURBSSURFACE */
|
||||||
POINTLIGHT = 304,
|
OBJECTTYPE = 300, /* OBJECTTYPE */
|
||||||
POLYGON = 305,
|
ORDER = 301, /* ORDER */
|
||||||
REF = 306,
|
OUTTANGENT = 302, /* OUTTANGENT */
|
||||||
RGBA = 307,
|
PATCH = 303, /* PATCH */
|
||||||
ROTATE = 308,
|
POINTLIGHT = 304, /* POINTLIGHT */
|
||||||
ROTX = 309,
|
POLYGON = 305, /* POLYGON */
|
||||||
ROTY = 310,
|
REF = 306, /* REF */
|
||||||
ROTZ = 311,
|
RGBA = 307, /* RGBA */
|
||||||
SANIM = 312,
|
ROTATE = 308, /* ROTATE */
|
||||||
SCALAR = 313,
|
ROTX = 309, /* ROTX */
|
||||||
SCALE = 314,
|
ROTY = 310, /* ROTY */
|
||||||
SEQUENCE = 315,
|
ROTZ = 311, /* ROTZ */
|
||||||
SHADING = 316,
|
SANIM = 312, /* SANIM */
|
||||||
SWITCH = 317,
|
SCALAR = 313, /* SCALAR */
|
||||||
SWITCHCONDITION = 318,
|
SCALE = 314, /* SCALE */
|
||||||
TABLE = 319,
|
SEQUENCE = 315, /* SEQUENCE */
|
||||||
TABLE_V = 320,
|
SHADING = 316, /* SHADING */
|
||||||
TAG = 321,
|
SWITCH = 317, /* SWITCH */
|
||||||
TANGENT = 322,
|
SWITCHCONDITION = 318, /* SWITCHCONDITION */
|
||||||
TEXLIST = 323,
|
TABLE = 319, /* TABLE */
|
||||||
TEXTURE = 324,
|
TABLE_V = 320, /* TABLE_V */
|
||||||
TLENGTHS = 325,
|
TAG = 321, /* TAG */
|
||||||
TRANSFORM = 326,
|
TANGENT = 322, /* TANGENT */
|
||||||
TRANSLATE = 327,
|
TEXLIST = 323, /* TEXLIST */
|
||||||
TREF = 328,
|
TEXTURE = 324, /* TEXTURE */
|
||||||
TRIANGLEFAN = 329,
|
TLENGTHS = 325, /* TLENGTHS */
|
||||||
TRIANGLESTRIP = 330,
|
TRANSFORM = 326, /* TRANSFORM */
|
||||||
TRIM = 331,
|
TRANSLATE = 327, /* TRANSLATE */
|
||||||
TXT = 332,
|
TREF = 328, /* TREF */
|
||||||
UKNOTS = 333,
|
TRIANGLEFAN = 329, /* TRIANGLEFAN */
|
||||||
UV = 334,
|
TRIANGLESTRIP = 330, /* TRIANGLESTRIP */
|
||||||
AUX = 335,
|
TRIM = 331, /* TRIM */
|
||||||
VKNOTS = 336,
|
TXT = 332, /* TXT */
|
||||||
VERTEX = 337,
|
UKNOTS = 333, /* UKNOTS */
|
||||||
VERTEXANIM = 338,
|
UV = 334, /* UV */
|
||||||
VERTEXPOOL = 339,
|
AUX = 335, /* AUX */
|
||||||
VERTEXREF = 340,
|
VKNOTS = 336, /* VKNOTS */
|
||||||
XFMANIM = 341,
|
VERTEX = 337, /* VERTEX */
|
||||||
XFMSANIM = 342,
|
VERTEXANIM = 338, /* VERTEXANIM */
|
||||||
START_EGG = 343,
|
VERTEXPOOL = 339, /* VERTEXPOOL */
|
||||||
START_GROUP_BODY = 344,
|
VERTEXREF = 340, /* VERTEXREF */
|
||||||
START_TEXTURE_BODY = 345,
|
XFMANIM = 341, /* XFMANIM */
|
||||||
START_PRIMITIVE_BODY = 346
|
XFMSANIM = 342, /* XFMSANIM */
|
||||||
|
START_EGG = 343, /* START_EGG */
|
||||||
|
START_GROUP_BODY = 344, /* START_GROUP_BODY */
|
||||||
|
START_TEXTURE_BODY = 345, /* START_TEXTURE_BODY */
|
||||||
|
START_PRIMITIVE_BODY = 346 /* START_PRIMITIVE_BODY */
|
||||||
};
|
};
|
||||||
|
typedef enum yytokentype yytoken_kind_t;
|
||||||
#endif
|
#endif
|
||||||
/* Tokens. */
|
/* Token kinds. */
|
||||||
|
#define YYEOF 0
|
||||||
|
#define YYerror 256
|
||||||
|
#define YYUNDEF 257
|
||||||
#define EGG_NUMBER 258
|
#define EGG_NUMBER 258
|
||||||
#define EGG_ULONG 259
|
#define EGG_ULONG 259
|
||||||
#define EGG_STRING 260
|
#define EGG_STRING 260
|
||||||
@ -232,9 +242,22 @@ extern int eggyydebug;
|
|||||||
|
|
||||||
/* Value type. */
|
/* Value type. */
|
||||||
|
|
||||||
|
/* Location type. */
|
||||||
|
#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
|
||||||
|
typedef struct YYLTYPE YYLTYPE;
|
||||||
|
struct YYLTYPE
|
||||||
|
{
|
||||||
|
int first_line;
|
||||||
|
int first_column;
|
||||||
|
int last_line;
|
||||||
|
int last_column;
|
||||||
|
};
|
||||||
|
# define YYLTYPE_IS_DECLARED 1
|
||||||
|
# define YYLTYPE_IS_TRIVIAL 1
|
||||||
|
#endif
|
||||||
|
|
||||||
extern YYSTYPE eggyylval;
|
|
||||||
|
|
||||||
int eggyyparse (void);
|
|
||||||
|
int eggyyparse (EggParserState &state, yyscan_t scanner);
|
||||||
|
|
||||||
#endif /* !YY_EGGYY_BUILT_TMP_PARSER_YXX_H_INCLUDED */
|
#endif /* !YY_EGGYY_BUILT_TMP_PARSER_YXX_H_INCLUDED */
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -27,12 +27,9 @@
|
|||||||
class EggGroupNode;
|
class EggGroupNode;
|
||||||
class LightMutex;
|
class LightMutex;
|
||||||
|
|
||||||
extern LightMutex egg_lock;
|
struct EggLexerState;
|
||||||
|
|
||||||
void egg_init_parser(std::istream &in, const std::string &filename,
|
bool egg_parse(EggLexerState &lexer, EggObject *tos, EggGroupNode *egg_top_node);
|
||||||
EggObject *tos, EggGroupNode *egg_top_node);
|
|
||||||
|
|
||||||
void egg_cleanup_parser();
|
|
||||||
|
|
||||||
// This structure holds the return value for each token. Traditionally, this
|
// This structure holds the return value for each token. Traditionally, this
|
||||||
// is a union, and is declared with the %union declaration in the parser.y
|
// is a union, and is declared with the %union declaration in the parser.y
|
||||||
@ -40,8 +37,7 @@ void egg_cleanup_parser();
|
|||||||
// that has member functions in a union), so we'll use a class instead. That
|
// that has member functions in a union), so we'll use a class instead. That
|
||||||
// means we need to declare it externally, here.
|
// means we need to declare it externally, here.
|
||||||
|
|
||||||
class EXPCL_PANDA_EGG EggTokenType {
|
struct EggTokenType {
|
||||||
public:
|
|
||||||
double _number;
|
double _number;
|
||||||
unsigned long _ulong;
|
unsigned long _ulong;
|
||||||
std::string _string;
|
std::string _string;
|
||||||
@ -53,4 +49,14 @@ public:
|
|||||||
// above class.
|
// above class.
|
||||||
#define YYSTYPE EggTokenType
|
#define YYSTYPE EggTokenType
|
||||||
|
|
||||||
|
struct EggLocType {
|
||||||
|
// Bison expects these members to be part of this struct.
|
||||||
|
int first_line;
|
||||||
|
int first_column;
|
||||||
|
int last_line;
|
||||||
|
int last_column;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define YYLTYPE EggLocType
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user