make an effort to use the official grammar

This commit is contained in:
David Rose 2004-10-04 10:25:04 +00:00
parent 8b29617612
commit 365a7db25f
8 changed files with 439 additions and 265 deletions

View File

@ -92,8 +92,12 @@ write_text(ostream &out, int indent_level) const {
out << "UCHAR"; out << "UCHAR";
break; break;
case T_byte: case T_sword:
out << "BYTE"; out << "SWORD";
break;
case T_sdword:
out << "SDWORD";
break; break;
case T_string: case T_string:

View File

@ -41,7 +41,8 @@ public:
T_double, T_double,
T_char, T_char,
T_uchar, T_uchar,
T_byte, T_sword,
T_sdword,
T_string, T_string,
T_cstring, T_cstring,
T_unicode, T_unicode,

View File

@ -32,7 +32,7 @@ get_guid() const {
// Access: Public // Access: Public
// Description: Sets whether the template is considered "open" or // Description: Sets whether the template is considered "open" or
// not. If it is open (this flag is true), the set of // not. If it is open (this flag is true), the set of
// restrictions is ignored and the instances of this // options is ignored and the instances of this
// template may include any types of children. If it is // template may include any types of children. If it is
// closed (false), only the named types may be added. // closed (false), only the named types may be added.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -46,7 +46,7 @@ set_open(bool open) {
// Access: Public // Access: Public
// Description: Returns whether the template is considered "open" or // Description: Returns whether the template is considered "open" or
// not. If it is open (this flag is true), the set of // not. If it is open (this flag is true), the set of
// restrictions is ignored and the instances of this // options is ignored and the instances of this
// template may include any types of children. If it is // template may include any types of children. If it is
// closed (false), only the named types may be added. // closed (false), only the named types may be added.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -56,36 +56,34 @@ get_open() const {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: XFileTemplate::add_restriction // Function: XFileTemplate::add_option
// Access: Public // Access: Public
// Description: Adds a new type to the list of allowable types of // Description: Adds a new type to the list of allowable types of
// child nodes for an instance of this template. The // child nodes for an instance of this template.
// method is a little misnamed; we are actually removing
// a restriction by adding this type to the list.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE void XFileTemplate:: INLINE void XFileTemplate::
add_restriction(XFileTemplate *restriction) { add_option(XFileTemplate *option) {
_restrictions.push_back(restriction); _options.push_back(option);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: XFileTemplate::get_num_restrictions // Function: XFileTemplate::get_num_options
// Access: Public // Access: Public
// Description: Returns the number of templates on the restrictions // Description: Returns the number of templates on the options
// list. // list.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE int XFileTemplate:: INLINE int XFileTemplate::
get_num_restrictions() const { get_num_options() const {
return _restrictions.size(); return _options.size();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: XFileTemplate::get_restriction // Function: XFileTemplate::get_option
// Access: Public // Access: Public
// Description: Returns the nth template on the restrictions list. // Description: Returns the nth template on the options list.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE XFileTemplate *XFileTemplate:: INLINE XFileTemplate *XFileTemplate::
get_restriction(int n) const { get_option(int n) const {
nassertr(n >= 0 && n < (int)_restrictions.size(), NULL); nassertr(n >= 0 && n < (int)_options.size(), NULL);
return _restrictions[n]; return _options[n];
} }

View File

@ -53,7 +53,7 @@ XFileTemplate::
void XFileTemplate:: void XFileTemplate::
clear() { clear() {
XFileNode::clear(); XFileNode::clear();
_restrictions.clear(); _options.clear();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -76,16 +76,16 @@ write_text(ostream &out, int indent_level) const {
indent(out, indent_level + 2) indent(out, indent_level + 2)
<< "[ ... ]\n"; << "[ ... ]\n";
} else if (!_restrictions.empty()) { } else if (!_options.empty()) {
// A restricted template // A restricted template
indent(out, indent_level + 2); indent(out, indent_level + 2);
char delimiter = '['; char delimiter = '[';
Restrictions::const_iterator ri; Options::const_iterator ri;
for (ri = _restrictions.begin(); ri != _restrictions.end(); ++ri) { for (ri = _options.begin(); ri != _options.end(); ++ri) {
XFileTemplate *restriction = (*ri); XFileTemplate *option = (*ri);
out << delimiter << " " out << delimiter << " "
<< restriction->get_name() << " <" << restriction->get_guid() << option->get_name() << " <" << option->get_guid()
<< ">"; << ">";
delimiter = ','; delimiter = ',';
} }

View File

@ -43,16 +43,16 @@ public:
INLINE void set_open(bool open); INLINE void set_open(bool open);
INLINE bool get_open() const; INLINE bool get_open() const;
INLINE void add_restriction(XFileTemplate *restriction); INLINE void add_option(XFileTemplate *option);
INLINE int get_num_restrictions() const; INLINE int get_num_options() const;
INLINE XFileTemplate *get_restriction(int n) const; INLINE XFileTemplate *get_option(int n) const;
private: private:
WindowsGuid _guid; WindowsGuid _guid;
bool _open; bool _open;
typedef pvector< PT(XFileTemplate) > Restrictions; typedef pvector< PT(XFileTemplate) > Options;
Restrictions _restrictions; Options _options;
public: public:
static TypeHandle get_class_type() { static TypeHandle get_class_type() {

View File

@ -10,6 +10,7 @@
#include "xParserDefs.h" #include "xParserDefs.h"
#include "xParser.h" #include "xParser.h"
#include "indent.h" #include "indent.h"
#include "string_utils.h"
#include "notify.h" #include "notify.h"
static int yyinput(void); // declared by flex. static int yyinput(void); // declared by flex.
@ -340,6 +341,42 @@ scan_guid_string() {
return result; return result;
} }
// Parses the text into a list of integers and returns them.
static PTA_int
parse_int_list(const string &text, const string &delimiter) {
PTA_int result;
vector_string words;
tokenize(text, words, delimiter);
vector_string::const_iterator wi;
for (wi = words.begin(); wi != words.end(); ++wi) {
int number = 0;
string_to_int(*wi, number);
result.push_back(number);
}
return result;
}
// Parses the text into a list of doubles and returns them.
static PTA_double
parse_double_list(const string &text, const string &delimiter) {
PTA_double result;
vector_string words;
tokenize(text, words, delimiter);
vector_string::const_iterator wi;
for (wi = words.begin(); wi != words.end(); ++wi) {
double number = 0;
string_to_double(*wi, number);
result.push_back(number);
}
return result;
}
// accept() is called below as each piece is pulled off and // accept() is called below as each piece is pulled off and
@ -351,7 +388,6 @@ inline void accept() {
%} %}
INTEGERNUM ([+-]?([0-9]+)) INTEGERNUM ([+-]?([0-9]+))
UNSIGNED_HEXNUM (0x[0-9a-fA-F]*)
REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?) REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
%% %%
@ -388,128 +424,161 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
accept(); accept();
} }
"{" {
accept();
return TOKEN_OBRACE;
}
"}" {
accept();
return TOKEN_CBRACE;
}
"[" {
accept();
return TOKEN_OBRACKET;
}
"]" {
accept();
return TOKEN_CBRACKET;
}
"." {
accept();
return TOKEN_DOT;
}
"," {
accept();
return TOKEN_COMMA;
}
";" {
accept();
return TOKEN_SEMICOLON;
}
"array" { "array" {
accept(); accept();
return KW_ARRAY; return TOKEN_ARRAY;
}
"binary" {
accept();
return KW_BINARY;
} }
"byte" { "byte" {
accept(); accept();
return KW_BYTE; return TOKEN_UCHAR;
} }
"char" { "char" {
accept(); accept();
return KW_CHAR; return TOKEN_CHAR;
} }
"cstring" { "cstring" {
accept(); accept();
return KW_CSTRING; return TOKEN_CSTRING;
} }
"double" { "double" {
accept(); accept();
return KW_DOUBLE; return TOKEN_DOUBLE;
} }
"dword" { "dword" {
accept(); accept();
return KW_DWORD; return TOKEN_DWORD;
}
"sdword" {
accept();
return TOKEN_SDWORD;
} }
"float" { "float" {
accept(); accept();
return KW_FLOAT; return TOKEN_FLOAT;
} }
"string" { "string" {
accept(); accept();
return KW_STRING; return TOKEN_LPSTR;
} }
"template" { "template" {
accept(); accept();
return KW_TEMPLATE; return TOKEN_TEMPLATE;
} }
"uchar" { "uchar" {
accept(); accept();
return KW_UCHAR; return TOKEN_UCHAR;
} }
"unicode" { "unicode" {
accept(); accept();
return KW_UNICODE; return TOKEN_UNICODE;
}
"sword" {
accept();
return TOKEN_SWORD;
} }
"word" { "word" {
accept(); accept();
return KW_WORD; return TOKEN_WORD;
} }
{INTEGERNUM} { {INTEGERNUM} {
// A signed or unsigned integer number. // A signed or unsigned integer number.
accept(); accept();
xyylval.u.s_int = atol(xyytext); xyylval.u.number = atol(xyytext);
xyylval.str = yytext; xyylval.str = yytext;
return INTEGER; return TOKEN_INTEGER;
} }
{UNSIGNED_HEXNUM} { ({INTEGERNUM};)+ {
// A hexadecimal integer number. // An integer as part of a semicolon-delimited list.
accept(); accept();
xyylval.int_list = parse_int_list(xyytext, ";");
xyylval.u.separator_token = TOKEN_SEMICOLON;
// As above, we'll decode the hex string by hand. return TOKEN_INTEGER_LIST;
xyylval.str = xyytext;
xyylval.u.s_int = 0;
const char *p = xyytext + 2;
while (*p != '\0') {
int next_value = xyylval.u.s_int * 16;
if (next_value < xyylval.u.s_int) {
xyyerror("Number out of range.");
xyylval.u.s_int = 1;
return INTEGER;
}
if (isalpha(*p)) {
xyylval.u.s_int = next_value + (tolower(*p) - 'a' + 10);
} else {
xyylval.u.s_int = next_value + (*p - '0');
}
++p;
}
return INTEGER;
} }
{REALNUM} { ({REALNUM};)+ {
// A floating-point number. // A floating-point number as part of a semicolon-delimited list.
accept(); accept();
xyylval.u.real = atof(xyytext); xyylval.double_list = parse_double_list(xyytext, ";");
xyylval.str = xyytext; xyylval.u.separator_token = TOKEN_SEMICOLON;
return REAL;
return TOKEN_REALNUM_LIST;
}
({INTEGERNUM},)+ {
// An integer as part of a semicolon-delimited list.
accept();
xyylval.int_list = parse_int_list(xyytext, ",");
xyylval.u.separator_token = TOKEN_COMMA;
return TOKEN_INTEGER_LIST;
}
({REALNUM},)+ {
// 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;
return TOKEN_REALNUM_LIST;
} }
["] { ["] {
// Quoted string. // Quoted string.
accept(); accept();
xyylval.str = scan_quoted_string('"'); xyylval.str = scan_quoted_string('"');
return STRING; return TOKEN_STRING;
}
['] {
// Single-quoted string.
accept();
xyylval.str = scan_quoted_string('\'');
return STRING;
} }
[<] { [<] {
@ -521,20 +590,14 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
xyyerror("Malformed GUID."); xyyerror("Malformed GUID.");
} }
return WINDOWS_GUID; return TOKEN_GUID;
} }
[A-Za-z_-][A-Za-z_0-9-]* { [A-Za-z_-][A-Za-z_0-9-]* {
// Identifier. // Identifier.
accept(); accept();
xyylval.str = xyytext; xyylval.str = xyytext;
return IDENTIFIER; return TOKEN_NAME;
} }
. {
// Send any other printable character as itself.
accept();
return xyytext[0];
}

View File

@ -3,6 +3,12 @@
// //
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// The grammar defined in this file is taken more-or-less from the
// Microsoft DirectX File Format Specification document, version 1.13.
// The document actually describes a slightly incomplete and incorrect
// grammar, so small changes had to be made, but an attempt was made
// to be as faithful as possible to the intention of the spec.
%{ %{
#include "xLexerDefs.h" #include "xLexerDefs.h"
#include "xParserDefs.h" #include "xParserDefs.h"
@ -45,114 +51,119 @@ x_cleanup_parser() {
%} %}
%token <u.s_int> INTEGER // These token values are taken from the DirectX spec; the particular
%token <u.real> REAL // numeric values are useful when reading an .x file in binary mode
%token <str> STRING IDENTIFIER // (which basically just streams the tokens retrieved by the lexer).
%token <guid> WINDOWS_GUID
%token KW_ARRAY %token <str> TOKEN_NAME 1
%token KW_BINARY %token <str> TOKEN_STRING 2
%token KW_BYTE %token <u.number> TOKEN_INTEGER 3
%token KW_CHAR %token <guid> TOKEN_GUID 5
%token KW_CSTRING %token <int_list> TOKEN_INTEGER_LIST 6
%token KW_DOUBLE %token <double_list> TOKEN_REALNUM_LIST 7
%token KW_DWORD
%token KW_FLOAT
%token KW_STRING
%token KW_TEMPLATE
%token KW_UCHAR
%token KW_UNICODE
%token KW_WORD
%type <u.node> xtemplate %token TOKEN_OBRACE 10
%type <u.node> data_object %token TOKEN_CBRACE 11
%type <str> optional_identifier %token TOKEN_OPAREN 12
%token TOKEN_CPAREN 13
%token TOKEN_OBRACKET 14
%token TOKEN_CBRACKET 15
%token TOKEN_OANGLE 16
%token TOKEN_CANGLE 17
%token TOKEN_DOT 18
%token TOKEN_COMMA 19
%token TOKEN_SEMICOLON 20
%token TOKEN_TEMPLATE 31
%token TOKEN_WORD 40
%token TOKEN_DWORD 41
%token TOKEN_FLOAT 42
%token TOKEN_DOUBLE 43
%token TOKEN_CHAR 44
%token TOKEN_UCHAR 45
%token TOKEN_SWORD 46
%token TOKEN_SDWORD 47
%token TOKEN_VOID 48
%token TOKEN_LPSTR 49
%token TOKEN_UNICODE 50
%token TOKEN_CSTRING 51
%token TOKEN_ARRAY 52
%type <u.node> template
%type <u.node> object
%type <u.primitive_type> primitive_type
%type <int_list> integer_list
%type <double_list> realnum_list
%type <str> name
%type <str> optional_name
%type <guid> class_id
%type <guid> optional_class_id
%% %%
xfile: xfile:
empty empty
| xfile xtemplate | xfile template
| xfile data_object | xfile object
; ;
xtemplate: template:
KW_TEMPLATE IDENTIFIER '{' WINDOWS_GUID TOKEN_TEMPLATE name TOKEN_OBRACE class_id
{ {
$$ = current_node; $$ = current_node;
XFileTemplate *templ = new XFileTemplate($2, $4); XFileTemplate *templ = new XFileTemplate($2, $4);
current_node->add_child(templ); current_node->add_child(templ);
current_node = templ; current_node = templ;
} }
template_members template_restrictions '}' template_parts TOKEN_CBRACE
{ {
$$ = current_node; $$ = current_node;
current_node = $<u.node>5; current_node = $<u.node>5;
} }
; ;
template_members: template_parts:
empty template_members_part TOKEN_OBRACKET template_option_info TOKEN_CBRACKET
| template_members template_member ';' | template_members_list
; ;
template_member: template_members_part:
data_def empty
| KW_ARRAY data_def array_dimensions | template_members_list
; ;
data_def: template_option_info:
KW_WORD optional_identifier ellipsis
{ {
current_data_def = new XFileDataDef(XFileDataDef::T_word, $2); DCAST(XFileTemplate, current_node)->set_open(true);
}
| template_option_list
;
template_members_list:
template_members
| template_members_list template_members
;
template_members:
primitive
| array
| template_reference
;
primitive:
primitive_type optional_name TOKEN_SEMICOLON
{
current_data_def = new XFileDataDef($1, $2);
current_node->add_child(current_data_def); current_node->add_child(current_data_def);
} }
| KW_DWORD optional_identifier ;
{
current_data_def = new XFileDataDef(XFileDataDef::T_dword, $2); array:
current_node->add_child(current_data_def); TOKEN_ARRAY array_data_type dimension_list TOKEN_SEMICOLON
} ;
| KW_FLOAT optional_identifier
{ template_reference:
current_data_def = new XFileDataDef(XFileDataDef::T_float, $2); name optional_name TOKEN_SEMICOLON
current_node->add_child(current_data_def);
}
| KW_DOUBLE optional_identifier
{
current_data_def = new XFileDataDef(XFileDataDef::T_double, $2);
current_node->add_child(current_data_def);
}
| KW_CHAR optional_identifier
{
current_data_def = new XFileDataDef(XFileDataDef::T_char, $2);
current_node->add_child(current_data_def);
}
| KW_UCHAR optional_identifier
{
current_data_def = new XFileDataDef(XFileDataDef::T_uchar, $2);
current_node->add_child(current_data_def);
}
| KW_BYTE optional_identifier
{
current_data_def = new XFileDataDef(XFileDataDef::T_byte, $2);
current_node->add_child(current_data_def);
}
| KW_STRING optional_identifier
{
current_data_def = new XFileDataDef(XFileDataDef::T_string, $2);
current_node->add_child(current_data_def);
}
| KW_CSTRING optional_identifier
{
current_data_def = new XFileDataDef(XFileDataDef::T_cstring, $2);
current_node->add_child(current_data_def);
}
| KW_UNICODE optional_identifier
{
current_data_def = new XFileDataDef(XFileDataDef::T_unicode, $2);
current_node->add_child(current_data_def);
}
| IDENTIFIER optional_identifier
{ {
XFileTemplate *xtemplate = x_file->find_template($1); XFileTemplate *xtemplate = x_file->find_template($1);
if (xtemplate == (XFileTemplate *)NULL) { if (xtemplate == (XFileTemplate *)NULL) {
@ -162,58 +173,118 @@ data_def:
current_node->add_child(current_data_def); current_node->add_child(current_data_def);
} }
} }
; ;
array_dimensions: primitive_type:
array_level TOKEN_WORD
| array_dimensions array_level {
; $$ = XFileDataDef::T_word;
}
| TOKEN_DWORD
{
$$ = XFileDataDef::T_dword;
}
| TOKEN_FLOAT
{
$$ = XFileDataDef::T_float;
}
| TOKEN_DOUBLE
{
$$ = XFileDataDef::T_double;
}
| TOKEN_CHAR
{
$$ = XFileDataDef::T_char;
}
| TOKEN_UCHAR
{
$$ = XFileDataDef::T_uchar;
}
| TOKEN_SWORD
{
$$ = XFileDataDef::T_sword;
}
| TOKEN_SDWORD
{
$$ = XFileDataDef::T_sdword;
}
| TOKEN_LPSTR
{
$$ = XFileDataDef::T_string;
}
| TOKEN_UNICODE
{
$$ = XFileDataDef::T_unicode;
}
| TOKEN_CSTRING
{
$$ = XFileDataDef::T_cstring;
}
;
array_level: array_data_type:
'[' INTEGER ']' primitive_type name
{ {
current_data_def->add_array_def(XFileArrayDef($2)); current_data_def = new XFileDataDef($1, $2);
current_node->add_child(current_data_def);
} }
| '[' IDENTIFIER ']' | name name
{
XFileNode *data_def = current_node->find_child($2);
if (data_def == (XFileNode *)NULL) {
yyerror("Unknown identifier: " + $2);
} else {
current_data_def->add_array_def(XFileArrayDef(DCAST(XFileDataDef, data_def)));
}
}
;
template_restrictions:
empty
| '[' '.' '.' '.' ']'
{
DCAST(XFileTemplate, current_node)->set_open(true);
}
| '[' template_restriction_list ']'
;
template_restriction_list:
template_restriction_element
{
}
| template_restriction_list ',' template_restriction_element
{
}
;
template_restriction_element:
IDENTIFIER
{ {
XFileTemplate *xtemplate = x_file->find_template($1); XFileTemplate *xtemplate = x_file->find_template($1);
if (xtemplate == (XFileTemplate *)NULL) { if (xtemplate == (XFileTemplate *)NULL) {
yyerror("Unknown template: " + $1); yyerror("Unknown template: " + $1);
} else { } else {
DCAST(XFileTemplate, current_node)->add_restriction(xtemplate); current_data_def = new XFileDataDef(XFileDataDef::T_template, $2, xtemplate);
current_node->add_child(current_data_def);
} }
} }
| IDENTIFIER WINDOWS_GUID ;
dimension_list:
dimension
| dimension_list dimension
;
dimension:
TOKEN_OBRACKET dimension_size TOKEN_CBRACKET
;
dimension_size:
TOKEN_INTEGER
{
current_data_def->add_array_def(XFileArrayDef($1));
}
| name
{
XFileNode *data_def = current_node->find_child($1);
if (data_def == (XFileNode *)NULL) {
yyerror("Unknown identifier: " + $1);
} else {
current_data_def->add_array_def(XFileArrayDef(DCAST(XFileDataDef, data_def)));
}
}
;
template_option_list:
template_option_part
{
}
| template_option_list template_option_part
{
}
;
template_option_part:
name
{
XFileTemplate *xtemplate = x_file->find_template($1);
if (xtemplate == (XFileTemplate *)NULL) {
yyerror("Unknown template: " + $1);
} else {
DCAST(XFileTemplate, current_node)->add_option(xtemplate);
}
}
| name TOKEN_GUID
{ {
XFileTemplate *xtemplate = x_file->find_template($2); XFileTemplate *xtemplate = x_file->find_template($2);
if (xtemplate == (XFileTemplate *)NULL) { if (xtemplate == (XFileTemplate *)NULL) {
@ -223,13 +294,41 @@ template_restriction_element:
xyywarning("GUID identifies template " + xtemplate->get_name() + xyywarning("GUID identifies template " + xtemplate->get_name() +
", not " + $1); ", not " + $1);
} }
DCAST(XFileTemplate, current_node)->add_restriction(xtemplate); DCAST(XFileTemplate, current_node)->add_option(xtemplate);
} }
} }
; ;
data_object: name:
IDENTIFIER optional_identifier '{' TOKEN_NAME
;
optional_name:
empty
{
$$ = string();
}
| name
;
class_id:
TOKEN_GUID
;
optional_class_id:
empty
{
$$ = WindowsGuid();
}
| class_id
;
ellipsis:
TOKEN_DOT TOKEN_DOT TOKEN_DOT
;
object:
name optional_name TOKEN_OBRACE
{ {
XFileTemplate *xtemplate = x_file->find_template($1); XFileTemplate *xtemplate = x_file->find_template($1);
$$ = current_node; $$ = current_node;
@ -243,55 +342,59 @@ data_object:
current_node = templ; current_node = templ;
} }
} }
data_object_members '}' optional_class_id data_parts_list TOKEN_CBRACE
{ {
$$ = current_node; $$ = current_node;
current_node = $<u.node>4; current_node = $<u.node>4;
} }
; ;
data_parts_list:
data_part
| data_parts_list data_part
;
data_object_members: data_part:
empty data_reference
| data_object_members data_object_member {
; }
| object
{
}
| integer_list
{
}
| realnum_list
{
}
| string list_separator
{
}
| list_separator
{
}
;
integer_list:
TOKEN_INTEGER_LIST
;
data_object_member: realnum_list:
data_object TOKEN_REALNUM_LIST
{ ;
}
| data_reference string:
{ TOKEN_STRING
} ;
| INTEGER
{ list_separator:
} TOKEN_SEMICOLON
| REAL | TOKEN_COMMA
{
}
| STRING
{
}
| ';'
{
}
| ','
{
}
; ;
data_reference: data_reference:
'{' IDENTIFIER '}' TOKEN_OBRACE name optional_class_id TOKEN_CBRACE
; ;
optional_identifier:
empty
{
$$ = string();
}
| IDENTIFIER
;
empty: empty:
; ;

View File

@ -20,8 +20,10 @@
#define XPARSERDEFS_H #define XPARSERDEFS_H
#include "pandatoolbase.h" #include "pandatoolbase.h"
#include "windowsGuid.h" #include "windowsGuid.h"
#include "xFileDataDef.h"
#include "pta_int.h"
#include "pta_double.h"
class XFile; class XFile;
class XFileNode; class XFileNode;
@ -40,12 +42,15 @@ int xyyparse();
class XTokenType { class XTokenType {
public: public:
union U { union U {
int s_int; int number;
double real;
XFileNode *node; XFileNode *node;
XFileDataDef::Type primitive_type;
int separator_token; // This is filled in for double_list and int_list.
} u; } u;
string str; string str;
WindowsGuid guid; WindowsGuid guid;
PTA_double double_list;
PTA_int int_list;
}; };
// The yacc-generated code expects to use the symbol 'YYSTYPE' to // The yacc-generated code expects to use the symbol 'YYSTYPE' to