more parsing games

This commit is contained in:
David Rose 2004-10-05 06:12:50 +00:00
parent e397109f73
commit b020b2047a
17 changed files with 569 additions and 67 deletions

View File

@ -20,6 +20,7 @@
#include "xParserDefs.h"
#include "xLexerDefs.h"
#include "xFileTemplate.h"
#include "xFileDataObject.h"
#include "config_xfile.h"
#include "standard_templates.h"
#include "zStream.h"
@ -36,7 +37,7 @@ PT(XFile) XFile::_standard_templates;
// Description:
////////////////////////////////////////////////////////////////////
XFile::
XFile() : XFileNode("") {
XFile() : XFileNode(this, "") {
_major_version = 3;
_minor_version = 2;
_format_type = FT_text;
@ -53,21 +54,6 @@ XFile::
clear();
}
////////////////////////////////////////////////////////////////////
// Function: XFile::add_child
// Access: Public, Virtual
// Description: Adds the indicated node as a child of this node.
////////////////////////////////////////////////////////////////////
void XFile::
add_child(XFileNode *node) {
XFileNode::add_child(node);
if (node->is_of_type(XFileTemplate::get_class_type())) {
XFileTemplate *xtemplate = DCAST(XFileTemplate, node);
_templates_by_guid[xtemplate->get_guid()] = xtemplate;
}
}
////////////////////////////////////////////////////////////////////
// Function: XFile::clear
// Access: Public, Virtual
@ -77,6 +63,8 @@ add_child(XFileNode *node) {
void XFile::
clear() {
XFileNode::clear();
_nodes_by_guid.clear();
}
////////////////////////////////////////////////////////////////////
@ -192,7 +180,7 @@ write(Filename filename) const {
}
////////////////////////////////////////////////////////////////////
// function: XFile::write
// Function: XFile::write
// Access: Public
// Description: Writes a parseable description of all the known
// nodes and templates to the stream.
@ -241,10 +229,11 @@ find_template(const string &name) const {
////////////////////////////////////////////////////////////////////
XFileTemplate *XFile::
find_template(const WindowsGuid &guid) const {
TemplatesByGuid::const_iterator gi;
gi = _templates_by_guid.find(guid);
if (gi != _templates_by_guid.end()) {
return (*gi).second;
NodesByGuid::const_iterator gi;
gi = _nodes_by_guid.find(guid);
if (gi != _nodes_by_guid.end() &&
(*gi).second->is_of_type(XFileTemplate::get_class_type())) {
return DCAST(XFileTemplate, (*gi).second);
}
const XFile *standard_templates = get_standard_templates();
@ -255,6 +244,41 @@ find_template(const WindowsGuid &guid) const {
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: XFile::find_data_object
// Access: Public
// Description: Returns the data object associated with the indicated
// name, if any, or NULL if none.
////////////////////////////////////////////////////////////////////
XFileDataObject *XFile::
find_data_object(const string &name) const {
XFileNode *child = find_descendent(name);
if (child != (XFileNode *)NULL &&
child->is_of_type(XFileDataObject::get_class_type())) {
return DCAST(XFileDataObject, child);
}
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: XFile::find_data_object
// Access: Public
// Description: Returns the data object associated with the indicated
// GUID, if any, or NULL if none.
////////////////////////////////////////////////////////////////////
XFileDataObject *XFile::
find_data_object(const WindowsGuid &guid) const {
NodesByGuid::const_iterator gi;
gi = _nodes_by_guid.find(guid);
if (gi != _nodes_by_guid.end() &&
(*gi).second->is_of_type(XFileDataObject::get_class_type())) {
return DCAST(XFileDataObject, (*gi).second);
}
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: XFile::write_text
// Access: Public, Virtual

View File

@ -27,6 +27,7 @@
#include "pointerTo.h"
class XFileTemplate;
class XFileDataObject;
////////////////////////////////////////////////////////////////////
// Class : XFile
@ -39,7 +40,6 @@ public:
XFile();
~XFile();
virtual void add_child(XFileNode *node);
virtual void clear();
bool read(Filename filename);
@ -51,6 +51,9 @@ public:
XFileTemplate *find_template(const string &name) const;
XFileTemplate *find_template(const WindowsGuid &guid) const;
XFileDataObject *find_data_object(const string &name) const;
XFileDataObject *find_data_object(const WindowsGuid &guid) const;
virtual void write_text(ostream &out, int indent_level) const;
enum FormatType {
@ -73,8 +76,8 @@ private:
FormatType _format_type;
FloatSize _float_size;
typedef pmap<WindowsGuid, XFileTemplate *> TemplatesByGuid;
TemplatesByGuid _templates_by_guid;
typedef pmap<WindowsGuid, XFileNode *> NodesByGuid;
NodesByGuid _nodes_by_guid;
static PT(XFile) _standard_templates;
@ -94,6 +97,8 @@ public:
private:
static TypeHandle _type_handle;
friend class XFileNode;
};
#include "xFile.I"

View File

@ -23,10 +23,58 @@
// Description:
////////////////////////////////////////////////////////////////////
INLINE XFileDataDef::
XFileDataDef(XFileDataDef::Type type, const string &name,
XFileTemplate *xtemplate) :
XFileNode(name),
XFileDataDef(XFile *x_file, const string &name,
XFileDataDef::Type type, XFileTemplate *xtemplate) :
XFileNode(x_file, name),
_type(type),
_template(xtemplate)
{
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataDef::get_data_type
// Access: Public
// Description: Returns the primitive type of this element, or
// T_template if this represents a nested template
// object.
////////////////////////////////////////////////////////////////////
INLINE XFileDataDef::Type XFileDataDef::
get_data_type() const {
return _type;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataDef::get_template
// Access: Public
// Description: If get_data_type() returned T_template, this returns
// the particular template pointer that this object
// represents.
////////////////////////////////////////////////////////////////////
INLINE XFileTemplate *XFileDataDef::
get_template() const {
return _template;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataDef::get_num_array_defs
// Access: Public
// Description: Returns the number of dimensions of array elements on
// this data object, or 0 if the data object is not an
// array.
////////////////////////////////////////////////////////////////////
INLINE int XFileDataDef::
get_num_array_defs() const {
return _array_def.size();
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataDef::get_array_def
// Access: Public
// Description: Returns the description of the nth dimension of array
// elements on this data object.
////////////////////////////////////////////////////////////////////
INLINE const XFileArrayDef &XFileDataDef::
get_array_def(int i) const {
nassertr(i >= 0 && i < (int)_array_def.size(), _array_def[0]);
return _array_def[i];
}

View File

@ -30,7 +30,10 @@
////////////////////////////////////////////////////////////////////
// Class : XFileDataDef
// Description : A definition of a single data element appearing
// within a template record.
// within a template record. This class represents the
// *definition* of the data element (e.g. DWORD
// nVertices); see XFileDataObject for its *value*
// (e.g. 12).
////////////////////////////////////////////////////////////////////
class XFileDataDef : public XFileNode {
public:
@ -49,13 +52,19 @@ public:
T_template,
};
INLINE XFileDataDef(Type type, const string &name,
XFileTemplate *xtemplate = NULL);
INLINE XFileDataDef(XFile *x_file, const string &name,
Type type, XFileTemplate *xtemplate = NULL);
virtual ~XFileDataDef();
virtual void clear();
void add_array_def(const XFileArrayDef &array_def);
INLINE Type get_data_type() const;
INLINE XFileTemplate *get_template() const;
INLINE int get_num_array_defs() const;
INLINE const XFileArrayDef &get_array_def(int i) const;
virtual void write_text(ostream &out, int indent_level) const;
private:

View File

@ -23,6 +23,121 @@
// Description:
////////////////////////////////////////////////////////////////////
INLINE XFileDataObject::
XFileDataObject(const string &name) : XFileNode(name)
XFileDataObject(XFile *x_file, const string &name) :
XFileNode(x_file, name)
{
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::get_data_def
// Access: Public
// Description: Returns the data object that this object is
// represented by, if any, or NULL if there is none.
////////////////////////////////////////////////////////////////////
INLINE XFileDataDef *XFileDataObject::
get_data_def() const {
return _data_def;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::i
// Access: Public
// Description: Unambiguously returns the object's representation as
// an integer, or 0 if the object has no integer
// representation. See also the typecast operators, and
// get_data_def() to determine what kind of
// representation this object has.
////////////////////////////////////////////////////////////////////
INLINE int XFileDataObject::
i() const {
return as_integer_value();
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::d
// Access: Public
// Description: Unambiguously returns the object's representation as
// a double, or 0.0 if the object has no double
// representation. See also the typecast operators, and
// get_data_def() to determine what kind of
// representation this object has.
////////////////////////////////////////////////////////////////////
INLINE double XFileDataObject::
d() const {
return as_double_value();
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::s
// Access: Public
// Description: Unambiguously returns the object's representation as
// a string, or empty string if the object has no string
// representation. See also the typecast operators, and
// get_data_def() to determine what kind of
// representation this object has.
////////////////////////////////////////////////////////////////////
INLINE string XFileDataObject::
s() const {
return as_string_value();
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::int typecast operator
// Access: Public
// Description: Returns the object's representation as an integer, or
// 0 if the object has no integer representation.
////////////////////////////////////////////////////////////////////
INLINE XFileDataObject::
operator int () const {
return as_integer_value();
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::double typecast operator
// Access: Public
// Description: Returns the object's representation as a double, or
// 0.0 if the object has no integer representation.
////////////////////////////////////////////////////////////////////
INLINE XFileDataObject::
operator double () const {
return as_double_value();
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::string typecast operator
// Access: Public
// Description: Returns the object's representation as a string, or
// empty string if the object has no string
// representation.
////////////////////////////////////////////////////////////////////
INLINE XFileDataObject::
operator string () const {
return as_string_value();
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::operator [] (int)
// Access: Public
// Description: Returns the nth nested object within this object.
// Call get_num_children() to determine the number of
// nested objects.
////////////////////////////////////////////////////////////////////
INLINE const XFileDataObject &XFileDataObject::
operator [] (int n) const {
nassertr(n >= 0 && n < get_num_children(), *this);
return *DCAST(XFileDataObject, get_child(n));
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::operator [] (string)
// Access: Public
// Description: Returns the named nested object within this object.
// It is an error if the named object does not exist.
// Call find_child() instead if there is any doubt.
////////////////////////////////////////////////////////////////////
INLINE const XFileDataObject &XFileDataObject::
operator [] (const string &name) const {
XFileNode *child = find_child(name);
nassertr(child != (XFileNode *)NULL, *this);
return *DCAST(XFileDataObject, child);
}

View File

@ -19,3 +19,36 @@
#include "xFileDataObject.h"
TypeHandle XFileDataObject::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::as_integer_value
// Access: Protected, Virtual
// Description: Returns the object's representation as an integer, if
// it has one.
////////////////////////////////////////////////////////////////////
int XFileDataObject::
as_integer_value() const {
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::as_double_value
// Access: Protected, Virtual
// Description: Returns the object's representation as a double, if
// it has one.
////////////////////////////////////////////////////////////////////
double XFileDataObject::
as_double_value() const {
return 0.0;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::as_string_value
// Access: Protected, Virtual
// Description: Returns the object's representation as a string, if
// it has one.
////////////////////////////////////////////////////////////////////
string XFileDataObject::
as_string_value() const {
return string();
}

View File

@ -21,6 +21,9 @@
#include "pandatoolbase.h"
#include "xFileNode.h"
#include "xFileDataDef.h"
#include "pointerTo.h"
#include "dcast.h"
////////////////////////////////////////////////////////////////////
// Class : XFileDataObject
@ -30,8 +33,27 @@
////////////////////////////////////////////////////////////////////
class XFileDataObject : public XFileNode {
public:
INLINE XFileDataObject(const string &name);
INLINE XFileDataObject(XFile *x_file, const string &name);
INLINE XFileDataDef *get_data_def() const;
INLINE int i() const;
INLINE double d() const;
INLINE string s() const;
INLINE operator int () const;
INLINE operator double () const;
INLINE operator string () const;
INLINE const XFileDataObject &operator [] (int n) const;
INLINE const XFileDataObject &operator [] (const string &name) const;
protected:
virtual int as_integer_value() const;
virtual double as_double_value() const;
virtual string as_string_value() const;
PT(XFileDataDef) _data_def;
public:
static TypeHandle get_class_type() {
return _type_handle;

View File

@ -27,8 +27,9 @@ TypeHandle XFileDataObjectTemplate::_type_handle;
// Description:
////////////////////////////////////////////////////////////////////
XFileDataObjectTemplate::
XFileDataObjectTemplate(XFileTemplate *xtemplate, const string &name) :
XFileDataObject(name),
XFileDataObjectTemplate(XFile *x_file, const string &name,
XFileTemplate *xtemplate) :
XFileDataObject(x_file, name),
_template(xtemplate)
{
}
@ -51,3 +52,72 @@ write_text(ostream &out, int indent_level) const {
indent(out, indent_level)
<< "}\n";
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObjectTemplate::add_parse_object
// Access: Public
// Description: Adds the indicated object as a nested object
// encountered in the parser. It will later be
// processed by finalize_parse_data().
////////////////////////////////////////////////////////////////////
void XFileDataObjectTemplate::
add_parse_object(XFileDataObjectTemplate *object, bool reference) {
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObjectTemplate::add_parse_double
// Access: Public
// Description: Adds the indicated list of doubles as a data element
// encountered in the parser. It will later be
// processed by finalize_parse_data().
////////////////////////////////////////////////////////////////////
void XFileDataObjectTemplate::
add_parse_double(PTA_double double_list, char separator) {
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObjectTemplate::add_parse_int
// Access: Public
// Description: Adds the indicated list of ints as a data element
// encountered in the parser. It will later be
// processed by finalize_parse_data().
////////////////////////////////////////////////////////////////////
void XFileDataObjectTemplate::
add_parse_int(PTA_int int_list, char separator) {
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObjectTemplate::add_parse_string
// Access: Public
// Description: Adds the indicated string as a data element
// encountered in the parser. It will later be
// processed by finalize_parse_data().
////////////////////////////////////////////////////////////////////
void XFileDataObjectTemplate::
add_parse_string(const string &str, char separator) {
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObjectTemplate::add_parse_separator
// Access: Public
// Description: Adds the indicated separator character as an isolated
// separator encountered in the parser. It will later
// be processed by finalize_parse_data().
////////////////////////////////////////////////////////////////////
void XFileDataObjectTemplate::
add_parse_separator(char separator) {
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObjectTemplate::finalize_parse_data
// Access: Public
// Description: Processes all of the data elements added by
// add_parse_*(), checks them for syntactic and semantic
// correctness against the Template definition, and
// stores the appropriate child data elements. Returns
// true on success, false if there is a mismatch.
////////////////////////////////////////////////////////////////////
bool XFileDataObjectTemplate::
finalize_parse_data() {
return true;
}

View File

@ -23,6 +23,8 @@
#include "xFileDataObject.h"
#include "xFileTemplate.h"
#include "pointerTo.h"
#include "pta_int.h"
#include "pta_double.h"
////////////////////////////////////////////////////////////////////
// Class : XFileDataObjectTemplate
@ -34,14 +36,48 @@
////////////////////////////////////////////////////////////////////
class XFileDataObjectTemplate : public XFileDataObject {
public:
XFileDataObjectTemplate(XFileTemplate *xtemplate, const string &name);
XFileDataObjectTemplate(XFile *x_file, const string &name,
XFileTemplate *xtemplate);
INLINE XFileTemplate *get_template() const;
virtual void write_text(ostream &out, int indent_level) const;
public:
void add_parse_object(XFileDataObjectTemplate *object, bool reference);
void add_parse_double(PTA_double double_list, char separator);
void add_parse_int(PTA_int int_list, char separator);
void add_parse_string(const string &str, char separator);
void add_parse_separator(char separator);
bool finalize_parse_data();
private:
PT(XFileTemplate) _template;
// This class is used to fill up the data as the values are parsed.
// It only has a temporary lifespan; it will be converted into
// actual data by finalize_parse_data().
enum ParseFlags {
PF_object = 0x001,
PF_reference = 0x002,
PF_double = 0x004,
PF_int = 0x008,
PF_string = 0x010,
PF_comma = 0x020,
PF_semicolon = 0x040,
};
class ParseData {
public:
PT(XFileDataObjectTemplate) _object;
PTA_double _double_list;
PTA_int _int_list;
string _string;
int _parse_flags;
};
typedef pvector<ParseData> ParseDataList;
ParseDataList _parse_data_list;
public:
static TypeHandle get_class_type() {

View File

@ -17,6 +17,8 @@
////////////////////////////////////////////////////////////////////
#include "xFileNode.h"
#include "windowsGuid.h"
#include "xFile.h"
TypeHandle XFileNode::_type_handle;
@ -26,7 +28,9 @@ TypeHandle XFileNode::_type_handle;
// Description:
////////////////////////////////////////////////////////////////////
XFileNode::
XFileNode(const string &name) : Namable(name)
XFileNode(XFile *x_file, const string &name) :
Namable(name),
_x_file(x_file)
{
}
@ -57,6 +61,53 @@ find_child(const string &name) const {
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: XFileNode::find_descendent
// Access: Public
// Description: Returns the first child or descendent found with the
// indicated name after a depth-first search, if any, or
// NULL if none.
////////////////////////////////////////////////////////////////////
XFileNode *XFileNode::
find_descendent(const string &name) const {
XFileNode *child = find_child(name);
if (child != (XFileNode *)NULL) {
return child;
}
Children::const_iterator ci;
for (ci = _children.begin(); ci != _children.end(); ++ci) {
XFileNode *child = (*ci)->find_descendent(name);
if (child != (XFileNode *)NULL){
return child;
}
}
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: XFileNode::has_guid
// Access: Public, Virtual
// Description: Returns true if this node has a GUID associated.
////////////////////////////////////////////////////////////////////
bool XFileNode::
has_guid() const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: XFileNode::get_guid
// Access: Public, Virtual
// Description: If has_guid() returned true, returns the particular
// GUID associated with this node.
////////////////////////////////////////////////////////////////////
const WindowsGuid &XFileNode::
get_guid() const {
static WindowsGuid empty;
return empty;
}
////////////////////////////////////////////////////////////////////
// Function: XFileNode::add_child
// Access: Public, Virtual
@ -68,6 +119,9 @@ add_child(XFileNode *node) {
if (node->has_name()) {
_children_by_name[node->get_name()] = node;
}
if (node->has_guid()) {
_x_file->_nodes_by_guid[node->get_guid()] = node;
}
}
////////////////////////////////////////////////////////////////////

View File

@ -27,6 +27,9 @@
#include "pvector.h"
#include "pmap.h"
class XFile;
class WindowsGuid;
////////////////////////////////////////////////////////////////////
// Class : XFileNode
// Description : A single node of an X file. This may be either a
@ -34,12 +37,16 @@
////////////////////////////////////////////////////////////////////
class XFileNode : public TypedReferenceCount, public Namable {
public:
XFileNode(const string &name);
XFileNode(XFile *x_file, const string &name);
virtual ~XFileNode();
INLINE int get_num_children() const;
INLINE XFileNode *get_child(int n) const;
XFileNode *find_child(const string &name) const;
XFileNode *find_descendent(const string &name) const;
virtual bool has_guid() const;
virtual const WindowsGuid &get_guid() const;
virtual void add_child(XFileNode *node);
virtual void clear();
@ -47,12 +54,14 @@ public:
virtual void write_text(ostream &out, int indent_level) const;
protected:
XFile *_x_file;
typedef pvector< PT(XFileNode) > Children;
Children _children;
typedef pmap<string, XFileNode *> ChildrenByName;
ChildrenByName _children_by_name;
public:
static TypeHandle get_class_type() {
return _type_handle;

View File

@ -17,16 +17,6 @@
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: XFileTemplate::get_guid
// Access: Public
// Description: Returns the GUID associated with this template.
////////////////////////////////////////////////////////////////////
INLINE const WindowsGuid &XFileTemplate::
get_guid() const {
return _guid;
}
////////////////////////////////////////////////////////////////////
// Function: XFileTemplate::set_open
// Access: Public

View File

@ -27,8 +27,8 @@ TypeHandle XFileTemplate::_type_handle;
// Description:
////////////////////////////////////////////////////////////////////
XFileTemplate::
XFileTemplate(const string &name, const WindowsGuid &guid) :
XFileNode(name),
XFileTemplate(XFile *x_file, const string &name, const WindowsGuid &guid) :
XFileNode(x_file, name),
_guid(guid),
_open(false)
{
@ -44,6 +44,26 @@ XFileTemplate::
clear();
}
////////////////////////////////////////////////////////////////////
// Function: XFileTemplate::has_guid
// Access: Public, Virtual
// Description: Returns true if this node has a GUID associated.
////////////////////////////////////////////////////////////////////
bool XFileTemplate::
has_guid() const {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: XFileTemplate::get_guid
// Access: Public, Virtual
// Description: Returns the GUID associated with this template.
////////////////////////////////////////////////////////////////////
const WindowsGuid &XFileTemplate::
get_guid() const {
return _guid;
}
////////////////////////////////////////////////////////////////////
// Function: XFileTemplate::clear
// Access: Public, Virtual

View File

@ -32,10 +32,11 @@ class XFileDataDef;
////////////////////////////////////////////////////////////////////
class XFileTemplate : public XFileNode {
public:
XFileTemplate(const string &name, const WindowsGuid &guid);
XFileTemplate(XFile *x_file, const string &name, const WindowsGuid &guid);
virtual ~XFileTemplate();
INLINE const WindowsGuid &get_guid() const;
virtual bool has_guid() const;
virtual const WindowsGuid &get_guid() const;
virtual void clear();
virtual void write_text(ostream &out, int indent_level) const;

View File

@ -542,7 +542,7 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
// An integer as part of a semicolon-delimited list.
accept();
xyylval.int_list = parse_int_list(xyytext, ";");
xyylval.u.separator_token = TOKEN_SEMICOLON;
xyylval.u.separator = ';';
return TOKEN_INTEGER_LIST;
}
@ -551,7 +551,7 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
// A floating-point number as part of a semicolon-delimited list.
accept();
xyylval.double_list = parse_double_list(xyytext, ";");
xyylval.u.separator_token = TOKEN_SEMICOLON;
xyylval.u.separator = ';';
return TOKEN_REALNUM_LIST;
}
@ -560,7 +560,7 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
// An integer as part of a semicolon-delimited list.
accept();
xyylval.int_list = parse_int_list(xyytext, ",");
xyylval.u.separator_token = TOKEN_COMMA;
xyylval.u.separator = ',';
return TOKEN_INTEGER_LIST;
}
@ -569,7 +569,7 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
// A floating-point number as part of a semicolon-delimited list.
accept();
xyylval.double_list = parse_double_list(xyytext, ",");
xyylval.u.separator_token = TOKEN_COMMA;
xyylval.u.separator = ',';
return TOKEN_REALNUM_LIST;
}

View File

@ -98,6 +98,8 @@ x_cleanup_parser() {
%type <str> string
%type <guid> class_id
%type <guid> optional_class_id
%type <u.separator> list_separator
%type <u.node> data_reference
%%
@ -111,7 +113,7 @@ template:
TOKEN_TEMPLATE name TOKEN_OBRACE class_id
{
$$ = current_node;
XFileTemplate *templ = new XFileTemplate($2, $4);
XFileTemplate *templ = new XFileTemplate(x_file, $2, $4);
current_node->add_child(templ);
current_node = templ;
}
@ -154,7 +156,7 @@ template_members:
primitive:
primitive_type optional_name TOKEN_SEMICOLON
{
current_data_def = new XFileDataDef($1, $2);
current_data_def = new XFileDataDef(x_file, $2, $1);
current_node->add_child(current_data_def);
}
;
@ -170,7 +172,7 @@ template_reference:
if (xtemplate == (XFileTemplate *)NULL) {
yyerror("Unknown template: " + $1);
} else {
current_data_def = new XFileDataDef(XFileDataDef::T_template, $2, xtemplate);
current_data_def = new XFileDataDef(x_file, $2, XFileDataDef::T_template, xtemplate);
current_node->add_child(current_data_def);
}
}
@ -226,7 +228,7 @@ primitive_type:
array_data_type:
primitive_type name
{
current_data_def = new XFileDataDef($1, $2);
current_data_def = new XFileDataDef(x_file, $2, $1);
current_node->add_child(current_data_def);
}
| name name
@ -235,7 +237,7 @@ array_data_type:
if (xtemplate == (XFileTemplate *)NULL) {
yyerror("Unknown template: " + $1);
} else {
current_data_def = new XFileDataDef(XFileDataDef::T_template, $2, xtemplate);
current_data_def = new XFileDataDef(x_file, $2, XFileDataDef::T_template, xtemplate);
current_node->add_child(current_data_def);
}
}
@ -285,7 +287,7 @@ template_option_part:
DCAST(XFileTemplate, current_node)->add_option(xtemplate);
}
}
| name TOKEN_GUID
| name class_id
{
XFileTemplate *xtemplate = x_file->find_template($2);
if (xtemplate == (XFileTemplate *)NULL) {
@ -338,13 +340,19 @@ object:
yyerror("Unknown template: " + $1);
} else {
XFileDataObjectTemplate *templ =
new XFileDataObjectTemplate(xtemplate, $2);
new XFileDataObjectTemplate(x_file, $2, xtemplate);
current_node->add_child(templ);
current_node = templ;
}
}
optional_class_id data_parts_list TOKEN_CBRACE
{
XFileDataObjectTemplate *current_template =
DCAST(XFileDataObjectTemplate, current_node);
if (!current_template->finalize_parse_data()) {
yyerror("Invalid data for object.");
}
$$ = current_node;
current_node = $<u.node>4;
}
@ -356,23 +364,53 @@ data_parts_list:
;
data_part:
data_reference
TOKEN_OBRACE data_reference TOKEN_CBRACE
{
if ($2 != (XFileNode *)NULL) {
if (!$2->is_of_type(XFileDataObjectTemplate::get_class_type())) {
// Actually, maybe you can--the docs aren't clear about this.
// But I don't think there's any real reason to.
yyerror("Can't reference primitive data type.");
} else {
XFileDataObjectTemplate *object =
DCAST(XFileDataObjectTemplate, $2);
XFileDataObjectTemplate *current_template =
DCAST(XFileDataObjectTemplate, current_node);
current_template->add_parse_object(object, true);
}
}
}
| object
{
XFileDataObjectTemplate *object =
DCAST(XFileDataObjectTemplate, $1);
XFileDataObjectTemplate *current_template =
DCAST(XFileDataObjectTemplate, current_node);
current_template->add_parse_object(object, false);
}
| integer_list
{
XFileDataObjectTemplate *current_template =
DCAST(XFileDataObjectTemplate, current_node);
current_template->add_parse_int($1, $<u.separator>1);
}
| realnum_list
{
XFileDataObjectTemplate *current_template =
DCAST(XFileDataObjectTemplate, current_node);
current_template->add_parse_double($1, $<u.separator>1);
}
| string list_separator
{
XFileDataObjectTemplate *current_template =
DCAST(XFileDataObjectTemplate, current_node);
current_template->add_parse_string($1, $2);
}
| list_separator
{
XFileDataObjectTemplate *current_template =
DCAST(XFileDataObjectTemplate, current_node);
current_template->add_parse_separator($1);
}
;
@ -390,11 +428,39 @@ string:
list_separator:
TOKEN_SEMICOLON
{
$$ = ';';
}
| TOKEN_COMMA
{
$$ = ',';
}
;
data_reference:
TOKEN_OBRACE name optional_class_id TOKEN_CBRACE
name
{
XFileDataObject *data_object = x_file->find_data_object($1);
if (data_object == (XFileDataObject *)NULL) {
yyerror("Unknown data_object: " + $1);
}
$$ = data_object;
}
| name class_id
{
XFileDataObject *data_object = x_file->find_data_object($2);
if (data_object == (XFileDataObject *)NULL) {
yyerror("Unknown data_object: " + $1);
} else {
if (data_object->get_name() != $1) {
xyywarning("GUID identifies data_object " + data_object->get_name() +
", not " + $1);
}
}
$$ = data_object;
}
;
empty:

View File

@ -45,7 +45,7 @@ public:
int number;
XFileNode *node;
XFileDataDef::Type primitive_type;
int separator_token; // This is filled in for double_list and int_list.
char separator; // This is filled in for double_list and int_list.
} u;
string str;
WindowsGuid guid;