mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -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";
|
||||
break;
|
||||
|
||||
case T_byte:
|
||||
out << "BYTE";
|
||||
case T_sword:
|
||||
out << "SWORD";
|
||||
break;
|
||||
|
||||
case T_sdword:
|
||||
out << "SDWORD";
|
||||
break;
|
||||
|
||||
case T_string:
|
||||
|
@ -41,7 +41,8 @@ public:
|
||||
T_double,
|
||||
T_char,
|
||||
T_uchar,
|
||||
T_byte,
|
||||
T_sword,
|
||||
T_sdword,
|
||||
T_string,
|
||||
T_cstring,
|
||||
T_unicode,
|
||||
|
@ -32,7 +32,7 @@ get_guid() const {
|
||||
// Access: Public
|
||||
// Description: Sets whether the template is considered "open" or
|
||||
// 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
|
||||
// closed (false), only the named types may be added.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -46,7 +46,7 @@ set_open(bool open) {
|
||||
// Access: Public
|
||||
// Description: Returns whether the template is considered "open" or
|
||||
// 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
|
||||
// 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
|
||||
// Description: Adds a new type to the list of allowable types of
|
||||
// child nodes for an instance of this template. The
|
||||
// method is a little misnamed; we are actually removing
|
||||
// a restriction by adding this type to the list.
|
||||
// child nodes for an instance of this template.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void XFileTemplate::
|
||||
add_restriction(XFileTemplate *restriction) {
|
||||
_restrictions.push_back(restriction);
|
||||
add_option(XFileTemplate *option) {
|
||||
_options.push_back(option);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileTemplate::get_num_restrictions
|
||||
// Function: XFileTemplate::get_num_options
|
||||
// Access: Public
|
||||
// Description: Returns the number of templates on the restrictions
|
||||
// Description: Returns the number of templates on the options
|
||||
// list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int XFileTemplate::
|
||||
get_num_restrictions() const {
|
||||
return _restrictions.size();
|
||||
get_num_options() const {
|
||||
return _options.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: XFileTemplate::get_restriction
|
||||
// Function: XFileTemplate::get_option
|
||||
// Access: Public
|
||||
// Description: Returns the nth template on the restrictions list.
|
||||
// Description: Returns the nth template on the options list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE XFileTemplate *XFileTemplate::
|
||||
get_restriction(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_restrictions.size(), NULL);
|
||||
return _restrictions[n];
|
||||
get_option(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_options.size(), NULL);
|
||||
return _options[n];
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ XFileTemplate::
|
||||
void XFileTemplate::
|
||||
clear() {
|
||||
XFileNode::clear();
|
||||
_restrictions.clear();
|
||||
_options.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -76,16 +76,16 @@ write_text(ostream &out, int indent_level) const {
|
||||
indent(out, indent_level + 2)
|
||||
<< "[ ... ]\n";
|
||||
|
||||
} else if (!_restrictions.empty()) {
|
||||
} else if (!_options.empty()) {
|
||||
// A restricted template
|
||||
indent(out, indent_level + 2);
|
||||
|
||||
char delimiter = '[';
|
||||
Restrictions::const_iterator ri;
|
||||
for (ri = _restrictions.begin(); ri != _restrictions.end(); ++ri) {
|
||||
XFileTemplate *restriction = (*ri);
|
||||
Options::const_iterator ri;
|
||||
for (ri = _options.begin(); ri != _options.end(); ++ri) {
|
||||
XFileTemplate *option = (*ri);
|
||||
out << delimiter << " "
|
||||
<< restriction->get_name() << " <" << restriction->get_guid()
|
||||
<< option->get_name() << " <" << option->get_guid()
|
||||
<< ">";
|
||||
delimiter = ',';
|
||||
}
|
||||
|
@ -43,16 +43,16 @@ public:
|
||||
INLINE void set_open(bool open);
|
||||
INLINE bool get_open() const;
|
||||
|
||||
INLINE void add_restriction(XFileTemplate *restriction);
|
||||
INLINE int get_num_restrictions() const;
|
||||
INLINE XFileTemplate *get_restriction(int n) const;
|
||||
INLINE void add_option(XFileTemplate *option);
|
||||
INLINE int get_num_options() const;
|
||||
INLINE XFileTemplate *get_option(int n) const;
|
||||
|
||||
private:
|
||||
WindowsGuid _guid;
|
||||
bool _open;
|
||||
|
||||
typedef pvector< PT(XFileTemplate) > Restrictions;
|
||||
Restrictions _restrictions;
|
||||
typedef pvector< PT(XFileTemplate) > Options;
|
||||
Options _options;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "xParserDefs.h"
|
||||
#include "xParser.h"
|
||||
#include "indent.h"
|
||||
#include "string_utils.h"
|
||||
#include "notify.h"
|
||||
|
||||
static int yyinput(void); // declared by flex.
|
||||
@ -340,6 +341,42 @@ scan_guid_string() {
|
||||
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
|
||||
@ -351,7 +388,6 @@ inline void accept() {
|
||||
%}
|
||||
|
||||
INTEGERNUM ([+-]?([0-9]+))
|
||||
UNSIGNED_HEXNUM (0x[0-9a-fA-F]*)
|
||||
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();
|
||||
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" {
|
||||
accept();
|
||||
return KW_ARRAY;
|
||||
}
|
||||
|
||||
"binary" {
|
||||
accept();
|
||||
return KW_BINARY;
|
||||
return TOKEN_ARRAY;
|
||||
}
|
||||
|
||||
"byte" {
|
||||
accept();
|
||||
return KW_BYTE;
|
||||
return TOKEN_UCHAR;
|
||||
}
|
||||
|
||||
"char" {
|
||||
accept();
|
||||
return KW_CHAR;
|
||||
return TOKEN_CHAR;
|
||||
}
|
||||
|
||||
"cstring" {
|
||||
accept();
|
||||
return KW_CSTRING;
|
||||
return TOKEN_CSTRING;
|
||||
}
|
||||
|
||||
"double" {
|
||||
accept();
|
||||
return KW_DOUBLE;
|
||||
return TOKEN_DOUBLE;
|
||||
}
|
||||
|
||||
"dword" {
|
||||
accept();
|
||||
return KW_DWORD;
|
||||
return TOKEN_DWORD;
|
||||
}
|
||||
|
||||
"sdword" {
|
||||
accept();
|
||||
return TOKEN_SDWORD;
|
||||
}
|
||||
|
||||
"float" {
|
||||
accept();
|
||||
return KW_FLOAT;
|
||||
return TOKEN_FLOAT;
|
||||
}
|
||||
|
||||
"string" {
|
||||
accept();
|
||||
return KW_STRING;
|
||||
return TOKEN_LPSTR;
|
||||
}
|
||||
|
||||
"template" {
|
||||
accept();
|
||||
return KW_TEMPLATE;
|
||||
return TOKEN_TEMPLATE;
|
||||
}
|
||||
|
||||
"uchar" {
|
||||
accept();
|
||||
return KW_UCHAR;
|
||||
return TOKEN_UCHAR;
|
||||
}
|
||||
|
||||
"unicode" {
|
||||
accept();
|
||||
return KW_UNICODE;
|
||||
return TOKEN_UNICODE;
|
||||
}
|
||||
|
||||
"sword" {
|
||||
accept();
|
||||
return TOKEN_SWORD;
|
||||
}
|
||||
|
||||
"word" {
|
||||
accept();
|
||||
return KW_WORD;
|
||||
return TOKEN_WORD;
|
||||
}
|
||||
|
||||
{INTEGERNUM} {
|
||||
// A signed or unsigned integer number.
|
||||
accept();
|
||||
xyylval.u.s_int = atol(xyytext);
|
||||
xyylval.u.number = atol(xyytext);
|
||||
xyylval.str = yytext;
|
||||
|
||||
return INTEGER;
|
||||
return TOKEN_INTEGER;
|
||||
}
|
||||
|
||||
{UNSIGNED_HEXNUM} {
|
||||
// A hexadecimal integer number.
|
||||
accept();
|
||||
({INTEGERNUM};)+ {
|
||||
// An integer as part of a semicolon-delimited list.
|
||||
accept();
|
||||
xyylval.int_list = parse_int_list(xyytext, ";");
|
||||
xyylval.u.separator_token = TOKEN_SEMICOLON;
|
||||
|
||||
// As above, we'll decode the hex string by hand.
|
||||
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;
|
||||
return TOKEN_INTEGER_LIST;
|
||||
}
|
||||
|
||||
{REALNUM} {
|
||||
// A floating-point number.
|
||||
({REALNUM};)+ {
|
||||
// A floating-point number as part of a semicolon-delimited list.
|
||||
accept();
|
||||
xyylval.u.real = atof(xyytext);
|
||||
xyylval.str = xyytext;
|
||||
return REAL;
|
||||
xyylval.double_list = parse_double_list(xyytext, ";");
|
||||
xyylval.u.separator_token = TOKEN_SEMICOLON;
|
||||
|
||||
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.
|
||||
accept();
|
||||
xyylval.str = scan_quoted_string('"');
|
||||
return STRING;
|
||||
}
|
||||
|
||||
['] {
|
||||
// Single-quoted string.
|
||||
accept();
|
||||
xyylval.str = scan_quoted_string('\'');
|
||||
return STRING;
|
||||
return TOKEN_STRING;
|
||||
}
|
||||
|
||||
[<] {
|
||||
@ -521,20 +590,14 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
||||
xyyerror("Malformed GUID.");
|
||||
}
|
||||
|
||||
return WINDOWS_GUID;
|
||||
return TOKEN_GUID;
|
||||
}
|
||||
|
||||
[A-Za-z_-][A-Za-z_0-9-]* {
|
||||
// Identifier.
|
||||
accept();
|
||||
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 "xParserDefs.h"
|
||||
@ -45,114 +51,119 @@ x_cleanup_parser() {
|
||||
|
||||
%}
|
||||
|
||||
%token <u.s_int> INTEGER
|
||||
%token <u.real> REAL
|
||||
%token <str> STRING IDENTIFIER
|
||||
%token <guid> WINDOWS_GUID
|
||||
// These token values are taken from the DirectX spec; the particular
|
||||
// numeric values are useful when reading an .x file in binary mode
|
||||
// (which basically just streams the tokens retrieved by the lexer).
|
||||
|
||||
%token KW_ARRAY
|
||||
%token KW_BINARY
|
||||
%token KW_BYTE
|
||||
%token KW_CHAR
|
||||
%token KW_CSTRING
|
||||
%token KW_DOUBLE
|
||||
%token KW_DWORD
|
||||
%token KW_FLOAT
|
||||
%token KW_STRING
|
||||
%token KW_TEMPLATE
|
||||
%token KW_UCHAR
|
||||
%token KW_UNICODE
|
||||
%token KW_WORD
|
||||
%token <str> TOKEN_NAME 1
|
||||
%token <str> TOKEN_STRING 2
|
||||
%token <u.number> TOKEN_INTEGER 3
|
||||
%token <guid> TOKEN_GUID 5
|
||||
%token <int_list> TOKEN_INTEGER_LIST 6
|
||||
%token <double_list> TOKEN_REALNUM_LIST 7
|
||||
|
||||
%type <u.node> xtemplate
|
||||
%type <u.node> data_object
|
||||
%type <str> optional_identifier
|
||||
%token TOKEN_OBRACE 10
|
||||
%token TOKEN_CBRACE 11
|
||||
%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:
|
||||
empty
|
||||
| xfile xtemplate
|
||||
| xfile data_object
|
||||
| xfile template
|
||||
| xfile object
|
||||
;
|
||||
|
||||
xtemplate:
|
||||
KW_TEMPLATE IDENTIFIER '{' WINDOWS_GUID
|
||||
template:
|
||||
TOKEN_TEMPLATE name TOKEN_OBRACE class_id
|
||||
{
|
||||
$$ = current_node;
|
||||
XFileTemplate *templ = new XFileTemplate($2, $4);
|
||||
current_node->add_child(templ);
|
||||
current_node = templ;
|
||||
}
|
||||
template_members template_restrictions '}'
|
||||
template_parts TOKEN_CBRACE
|
||||
{
|
||||
$$ = current_node;
|
||||
current_node = $<u.node>5;
|
||||
}
|
||||
;
|
||||
;
|
||||
|
||||
template_members:
|
||||
empty
|
||||
| template_members template_member ';'
|
||||
;
|
||||
template_parts:
|
||||
template_members_part TOKEN_OBRACKET template_option_info TOKEN_CBRACKET
|
||||
| template_members_list
|
||||
;
|
||||
|
||||
template_member:
|
||||
data_def
|
||||
| KW_ARRAY data_def array_dimensions
|
||||
;
|
||||
template_members_part:
|
||||
empty
|
||||
| template_members_list
|
||||
;
|
||||
|
||||
data_def:
|
||||
KW_WORD optional_identifier
|
||||
template_option_info:
|
||||
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);
|
||||
}
|
||||
| KW_DWORD optional_identifier
|
||||
{
|
||||
current_data_def = new XFileDataDef(XFileDataDef::T_dword, $2);
|
||||
current_node->add_child(current_data_def);
|
||||
}
|
||||
| KW_FLOAT optional_identifier
|
||||
{
|
||||
current_data_def = new XFileDataDef(XFileDataDef::T_float, $2);
|
||||
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
|
||||
;
|
||||
|
||||
array:
|
||||
TOKEN_ARRAY array_data_type dimension_list TOKEN_SEMICOLON
|
||||
;
|
||||
|
||||
template_reference:
|
||||
name optional_name TOKEN_SEMICOLON
|
||||
{
|
||||
XFileTemplate *xtemplate = x_file->find_template($1);
|
||||
if (xtemplate == (XFileTemplate *)NULL) {
|
||||
@ -162,58 +173,118 @@ data_def:
|
||||
current_node->add_child(current_data_def);
|
||||
}
|
||||
}
|
||||
;
|
||||
;
|
||||
|
||||
array_dimensions:
|
||||
array_level
|
||||
| array_dimensions array_level
|
||||
;
|
||||
primitive_type:
|
||||
TOKEN_WORD
|
||||
{
|
||||
$$ = 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:
|
||||
'[' INTEGER ']'
|
||||
array_data_type:
|
||||
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 ']'
|
||||
{
|
||||
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
|
||||
| name name
|
||||
{
|
||||
XFileTemplate *xtemplate = x_file->find_template($1);
|
||||
if (xtemplate == (XFileTemplate *)NULL) {
|
||||
yyerror("Unknown template: " + $1);
|
||||
} 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);
|
||||
if (xtemplate == (XFileTemplate *)NULL) {
|
||||
@ -223,13 +294,41 @@ template_restriction_element:
|
||||
xyywarning("GUID identifies template " + xtemplate->get_name() +
|
||||
", not " + $1);
|
||||
}
|
||||
DCAST(XFileTemplate, current_node)->add_restriction(xtemplate);
|
||||
DCAST(XFileTemplate, current_node)->add_option(xtemplate);
|
||||
}
|
||||
}
|
||||
;
|
||||
;
|
||||
|
||||
data_object:
|
||||
IDENTIFIER optional_identifier '{'
|
||||
name:
|
||||
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);
|
||||
$$ = current_node;
|
||||
@ -243,55 +342,59 @@ data_object:
|
||||
current_node = templ;
|
||||
}
|
||||
}
|
||||
data_object_members '}'
|
||||
optional_class_id data_parts_list TOKEN_CBRACE
|
||||
{
|
||||
$$ = current_node;
|
||||
current_node = $<u.node>4;
|
||||
}
|
||||
;
|
||||
|
||||
data_parts_list:
|
||||
data_part
|
||||
| data_parts_list data_part
|
||||
;
|
||||
|
||||
data_object_members:
|
||||
empty
|
||||
| data_object_members data_object_member
|
||||
;
|
||||
data_part:
|
||||
data_reference
|
||||
{
|
||||
}
|
||||
| object
|
||||
{
|
||||
}
|
||||
| integer_list
|
||||
{
|
||||
}
|
||||
| realnum_list
|
||||
{
|
||||
}
|
||||
| string list_separator
|
||||
{
|
||||
}
|
||||
| list_separator
|
||||
{
|
||||
}
|
||||
;
|
||||
|
||||
integer_list:
|
||||
TOKEN_INTEGER_LIST
|
||||
;
|
||||
|
||||
data_object_member:
|
||||
data_object
|
||||
{
|
||||
}
|
||||
| data_reference
|
||||
{
|
||||
}
|
||||
| INTEGER
|
||||
{
|
||||
}
|
||||
| REAL
|
||||
{
|
||||
}
|
||||
| STRING
|
||||
{
|
||||
}
|
||||
| ';'
|
||||
{
|
||||
}
|
||||
| ','
|
||||
{
|
||||
}
|
||||
realnum_list:
|
||||
TOKEN_REALNUM_LIST
|
||||
;
|
||||
|
||||
string:
|
||||
TOKEN_STRING
|
||||
;
|
||||
|
||||
list_separator:
|
||||
TOKEN_SEMICOLON
|
||||
| TOKEN_COMMA
|
||||
;
|
||||
|
||||
data_reference:
|
||||
'{' IDENTIFIER '}'
|
||||
;
|
||||
|
||||
optional_identifier:
|
||||
empty
|
||||
{
|
||||
$$ = string();
|
||||
}
|
||||
| IDENTIFIER
|
||||
;
|
||||
TOKEN_OBRACE name optional_class_id TOKEN_CBRACE
|
||||
;
|
||||
|
||||
empty:
|
||||
;
|
||||
|
||||
|
@ -20,8 +20,10 @@
|
||||
#define XPARSERDEFS_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include "windowsGuid.h"
|
||||
#include "xFileDataDef.h"
|
||||
#include "pta_int.h"
|
||||
#include "pta_double.h"
|
||||
|
||||
class XFile;
|
||||
class XFileNode;
|
||||
@ -40,12 +42,15 @@ int xyyparse();
|
||||
class XTokenType {
|
||||
public:
|
||||
union U {
|
||||
int s_int;
|
||||
double real;
|
||||
int number;
|
||||
XFileNode *node;
|
||||
XFileDataDef::Type primitive_type;
|
||||
int separator_token; // This is filled in for double_list and int_list.
|
||||
} u;
|
||||
string str;
|
||||
WindowsGuid guid;
|
||||
PTA_double double_list;
|
||||
PTA_int int_list;
|
||||
};
|
||||
|
||||
// The yacc-generated code expects to use the symbol 'YYSTYPE' to
|
||||
|
Loading…
x
Reference in New Issue
Block a user