mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
make an effort to use the official grammar
This commit is contained in:
parent
8b29617612
commit
365a7db25f
@ -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:
|
||||||
|
@ -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,
|
||||||
|
@ -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];
|
||||||
}
|
}
|
||||||
|
@ -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 = ',';
|
||||||
}
|
}
|
||||||
|
@ -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() {
|
||||||
|
@ -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)) {
|
({REALNUM};)+ {
|
||||||
xyylval.u.s_int = next_value + (tolower(*p) - 'a' + 10);
|
// A floating-point number as part of a semicolon-delimited list.
|
||||||
} else {
|
|
||||||
xyylval.u.s_int = next_value + (*p - '0');
|
|
||||||
}
|
|
||||||
++p;
|
|
||||||
}
|
|
||||||
|
|
||||||
return INTEGER;
|
|
||||||
}
|
|
||||||
|
|
||||||
{REALNUM} {
|
|
||||||
// A floating-point number.
|
|
||||||
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];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
template_members_part TOKEN_OBRACKET template_option_info TOKEN_CBRACKET
|
||||||
|
| template_members_list
|
||||||
|
;
|
||||||
|
|
||||||
|
template_members_part:
|
||||||
empty
|
empty
|
||||||
| template_members template_member ';'
|
| template_members_list
|
||||||
;
|
;
|
||||||
|
|
||||||
template_member:
|
template_option_info:
|
||||||
data_def
|
ellipsis
|
||||||
| KW_ARRAY data_def array_dimensions
|
{
|
||||||
|
DCAST(XFileTemplate, current_node)->set_open(true);
|
||||||
|
}
|
||||||
|
| template_option_list
|
||||||
;
|
;
|
||||||
|
|
||||||
data_def:
|
template_members_list:
|
||||||
KW_WORD optional_identifier
|
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(XFileDataDef::T_word, $2);
|
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) {
|
||||||
@ -164,56 +175,116 @@ 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);
|
XFileTemplate *xtemplate = x_file->find_template($1);
|
||||||
|
if (xtemplate == (XFileTemplate *)NULL) {
|
||||||
|
yyerror("Unknown template: " + $1);
|
||||||
|
} else {
|
||||||
|
current_data_def = new XFileDataDef(XFileDataDef::T_template, $2, xtemplate);
|
||||||
|
current_node->add_child(current_data_def);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
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) {
|
if (data_def == (XFileNode *)NULL) {
|
||||||
yyerror("Unknown identifier: " + $2);
|
yyerror("Unknown identifier: " + $1);
|
||||||
} else {
|
} else {
|
||||||
current_data_def->add_array_def(XFileArrayDef(DCAST(XFileDataDef, data_def)));
|
current_data_def->add_array_def(XFileArrayDef(DCAST(XFileDataDef, data_def)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
template_restrictions:
|
template_option_list:
|
||||||
empty
|
template_option_part
|
||||||
| '[' '.' '.' '.' ']'
|
|
||||||
{
|
|
||||||
DCAST(XFileTemplate, current_node)->set_open(true);
|
|
||||||
}
|
|
||||||
| '[' template_restriction_list ']'
|
|
||||||
;
|
|
||||||
|
|
||||||
template_restriction_list:
|
|
||||||
template_restriction_element
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
| template_restriction_list ',' template_restriction_element
|
| template_option_list template_option_part
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
template_restriction_element:
|
template_option_part:
|
||||||
IDENTIFIER
|
name
|
||||||
{
|
{
|
||||||
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);
|
DCAST(XFileTemplate, current_node)->add_option(xtemplate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| IDENTIFIER WINDOWS_GUID
|
| 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_object_members:
|
data_part
|
||||||
empty
|
| data_parts_list data_part
|
||||||
| data_object_members data_object_member
|
|
||||||
;
|
;
|
||||||
|
|
||||||
data_object_member:
|
data_part:
|
||||||
data_object
|
data_reference
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
| data_reference
|
| object
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
| INTEGER
|
| integer_list
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
| REAL
|
| realnum_list
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
| STRING
|
| string list_separator
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
| ';'
|
| list_separator
|
||||||
{
|
|
||||||
}
|
|
||||||
| ','
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
integer_list:
|
||||||
|
TOKEN_INTEGER_LIST
|
||||||
|
;
|
||||||
|
|
||||||
|
realnum_list:
|
||||||
|
TOKEN_REALNUM_LIST
|
||||||
|
;
|
||||||
|
|
||||||
|
string:
|
||||||
|
TOKEN_STRING
|
||||||
|
;
|
||||||
|
|
||||||
|
list_separator:
|
||||||
|
TOKEN_SEMICOLON
|
||||||
|
| TOKEN_COMMA
|
||||||
|
;
|
||||||
|
|
||||||
data_reference:
|
data_reference:
|
||||||
'{' IDENTIFIER '}'
|
TOKEN_OBRACE name optional_class_id TOKEN_CBRACE
|
||||||
;
|
|
||||||
|
|
||||||
optional_identifier:
|
|
||||||
empty
|
|
||||||
{
|
|
||||||
$$ = string();
|
|
||||||
}
|
|
||||||
| IDENTIFIER
|
|
||||||
;
|
;
|
||||||
|
|
||||||
empty:
|
empty:
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user