mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-29 16:20:11 -04:00
cppparser: Fix slow parser performance
This commit is contained in:
parent
acf118c96a
commit
04a9264e68
@ -31,37 +31,6 @@ CPPFile(const Filename &filename, const Filename &filename_as_referenced,
|
|||||||
_filename_as_referenced.set_text();
|
_filename_as_referenced.set_text();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
CPPFile::
|
|
||||||
CPPFile(const CPPFile ©) :
|
|
||||||
_filename(copy._filename),
|
|
||||||
_filename_as_referenced(copy._filename_as_referenced),
|
|
||||||
_source(copy._source),
|
|
||||||
_pragma_once(copy._pragma_once)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void CPPFile::
|
|
||||||
operator = (const CPPFile ©) {
|
|
||||||
_filename = copy._filename;
|
|
||||||
_filename_as_referenced = copy._filename_as_referenced;
|
|
||||||
_source = copy._source;
|
|
||||||
_pragma_once = copy._pragma_once;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
CPPFile::
|
|
||||||
~CPPFile() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the file appears to be a C or C++ source code file based on
|
* Returns true if the file appears to be a C or C++ source code file based on
|
||||||
* its extension. That is, returns true if the filename ends in .c, .C, .cc,
|
* its extension. That is, returns true if the filename ends in .c, .C, .cc,
|
||||||
|
@ -34,9 +34,6 @@ public:
|
|||||||
CPPFile(const Filename &filename = "",
|
CPPFile(const Filename &filename = "",
|
||||||
const Filename &filename_as_referenced = "",
|
const Filename &filename_as_referenced = "",
|
||||||
Source source = S_none);
|
Source source = S_none);
|
||||||
CPPFile(const CPPFile ©);
|
|
||||||
void operator = (const CPPFile ©);
|
|
||||||
~CPPFile();
|
|
||||||
|
|
||||||
bool is_c_or_i_file() const;
|
bool is_c_or_i_file() const;
|
||||||
static bool is_c_or_i_file(const Filename &filename);
|
static bool is_c_or_i_file(const Filename &filename);
|
||||||
|
@ -325,8 +325,8 @@ extract_args(vector_string &args, const string &expr, size_t &p) const {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
string CPPManifest::
|
string CPPManifest::
|
||||||
expand(const vector_string &args, const Manifests &manifests, bool expand_undefined) const {
|
expand(const vector_string &args, bool expand_undefined, const Ignores &ignores) const {
|
||||||
return r_expand(_expansion, args, manifests, expand_undefined);
|
return r_expand(_expansion, args, expand_undefined, ignores);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -601,7 +601,7 @@ save_expansion(Expansion &expansion, const string &exp, const vector_string &par
|
|||||||
*/
|
*/
|
||||||
string CPPManifest::
|
string CPPManifest::
|
||||||
r_expand(const Expansion &expansion, const vector_string &args,
|
r_expand(const Expansion &expansion, const vector_string &args,
|
||||||
const Manifests &manifests, bool expand_undefined) const {
|
bool expand_undefined, const Ignores &ignores) const {
|
||||||
std::string result;
|
std::string result;
|
||||||
|
|
||||||
for (const ExpansionNode &node : expansion) {
|
for (const ExpansionNode &node : expansion) {
|
||||||
@ -631,7 +631,7 @@ r_expand(const Expansion &expansion, const vector_string &args,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (node._expand) {
|
if (node._expand) {
|
||||||
_parser.expand_manifests(subst, manifests, expand_undefined);
|
_parser.expand_manifests(subst, expand_undefined, ignores);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!subst.empty()) {
|
if (!subst.empty()) {
|
||||||
@ -654,7 +654,7 @@ r_expand(const Expansion &expansion, const vector_string &args,
|
|||||||
if (!node._nested.empty()) {
|
if (!node._nested.empty()) {
|
||||||
string nested_result;
|
string nested_result;
|
||||||
if (node._optional && args.size() >= _num_parameters) {
|
if (node._optional && args.size() >= _num_parameters) {
|
||||||
nested_result = r_expand(node._nested, args, manifests, expand_undefined);
|
nested_result = r_expand(node._nested, args, expand_undefined, ignores);
|
||||||
}
|
}
|
||||||
if (node._stringify) {
|
if (node._stringify) {
|
||||||
nested_result = stringify(nested_result);
|
nested_result = stringify(nested_result);
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "cppBisonDefs.h"
|
#include "cppBisonDefs.h"
|
||||||
|
|
||||||
#include "vector_string.h"
|
#include "vector_string.h"
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
class CPPExpression;
|
class CPPExpression;
|
||||||
class CPPType;
|
class CPPType;
|
||||||
@ -30,7 +31,7 @@ class CPPType;
|
|||||||
*/
|
*/
|
||||||
class CPPManifest {
|
class CPPManifest {
|
||||||
public:
|
public:
|
||||||
typedef std::map<std::string, CPPManifest *> Manifests;
|
typedef std::unordered_set<const CPPManifest *> Ignores;
|
||||||
|
|
||||||
CPPManifest(const CPPPreprocessor &parser, const std::string &args, const cppyyltype &loc);
|
CPPManifest(const CPPPreprocessor &parser, const std::string &args, const cppyyltype &loc);
|
||||||
CPPManifest(const CPPPreprocessor &parser, const std::string ¯o, const std::string &definition);
|
CPPManifest(const CPPPreprocessor &parser, const std::string ¯o, const std::string &definition);
|
||||||
@ -39,8 +40,8 @@ public:
|
|||||||
static std::string stringify(const std::string &source);
|
static std::string stringify(const std::string &source);
|
||||||
void extract_args(vector_string &args, const std::string &expr, size_t &p) const;
|
void extract_args(vector_string &args, const std::string &expr, size_t &p) const;
|
||||||
std::string expand(const vector_string &args = vector_string(),
|
std::string expand(const vector_string &args = vector_string(),
|
||||||
const Manifests &manifests = Manifests(),
|
bool expand_undefined = false,
|
||||||
bool expand_undefined = false) const;
|
const Ignores &ignores = Ignores()) const;
|
||||||
|
|
||||||
|
|
||||||
CPPType *determine_type() const;
|
CPPType *determine_type() const;
|
||||||
@ -86,7 +87,7 @@ private:
|
|||||||
const vector_string ¶meter_names);
|
const vector_string ¶meter_names);
|
||||||
|
|
||||||
std::string r_expand(const Expansion &expansion, const vector_string &args,
|
std::string r_expand(const Expansion &expansion, const vector_string &args,
|
||||||
const Manifests &manifests, bool expand_undefined) const;
|
bool expand_undefined, const Ignores &ignores) const;
|
||||||
|
|
||||||
Expansion _expansion;
|
Expansion _expansion;
|
||||||
};
|
};
|
||||||
|
@ -902,7 +902,8 @@ push_expansion(const string &input, const CPPManifest *manifest, const YYLTYPE &
|
|||||||
* Given a string, expand all manifests within the string.
|
* Given a string, expand all manifests within the string.
|
||||||
*/
|
*/
|
||||||
void CPPPreprocessor::
|
void CPPPreprocessor::
|
||||||
expand_manifests(string &expr, const Manifests &manifests, bool expand_undefined) const {
|
expand_manifests(string &expr, bool expand_undefined,
|
||||||
|
const CPPManifest::Ignores &ignores) const {
|
||||||
size_t p = 0;
|
size_t p = 0;
|
||||||
while (p < expr.size()) {
|
while (p < expr.size()) {
|
||||||
if (isalpha(expr[p]) || expr[p] == '_') {
|
if (isalpha(expr[p]) || expr[p] == '_') {
|
||||||
@ -925,8 +926,8 @@ expand_manifests(string &expr, const Manifests &manifests, bool expand_undefined
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Is it a manifest?
|
// Is it a manifest?
|
||||||
Manifests::const_iterator mi = manifests.find(ident);
|
Manifests::const_iterator mi = _manifests.find(ident);
|
||||||
if (mi != manifests.end()) {
|
if (mi != _manifests.end() && ignores.count((*mi).second) == 0) {
|
||||||
const CPPManifest *manifest = (*mi).second;
|
const CPPManifest *manifest = (*mi).second;
|
||||||
vector_string args;
|
vector_string args;
|
||||||
if (manifest->_has_parameters) {
|
if (manifest->_has_parameters) {
|
||||||
@ -943,11 +944,11 @@ expand_manifests(string &expr, const Manifests &manifests, bool expand_undefined
|
|||||||
|
|
||||||
// Don't consider this manifest when expanding the arguments or
|
// Don't consider this manifest when expanding the arguments or
|
||||||
// result, to prevent recursion.
|
// result, to prevent recursion.
|
||||||
Manifests nested_manifests(manifests);
|
CPPManifest::Ignores nested_ignores(ignores);
|
||||||
nested_manifests.erase((*mi).first);
|
nested_ignores.insert(manifest);
|
||||||
|
|
||||||
string result = manifest->expand(args);
|
string result = manifest->expand(args, expand_undefined, nested_ignores);
|
||||||
expand_manifests(result, nested_manifests, expand_undefined);
|
expand_manifests(result, expand_undefined, nested_ignores);
|
||||||
|
|
||||||
expr = expr.substr(0, q) + result + expr.substr(p);
|
expr = expr.substr(0, q) + result + expr.substr(p);
|
||||||
p = q + result.size();
|
p = q + result.size();
|
||||||
@ -1008,7 +1009,7 @@ CPPExpression *CPPPreprocessor::
|
|||||||
parse_expr(const string &input_expr, CPPScope *current_scope,
|
parse_expr(const string &input_expr, CPPScope *current_scope,
|
||||||
CPPScope *global_scope, const YYLTYPE &loc) {
|
CPPScope *global_scope, const YYLTYPE &loc) {
|
||||||
string expr = input_expr;
|
string expr = input_expr;
|
||||||
expand_manifests(expr, _manifests, false);
|
expand_manifests(expr, false);
|
||||||
|
|
||||||
CPPExpressionParser ep(current_scope, global_scope);
|
CPPExpressionParser ep(current_scope, global_scope);
|
||||||
ep._verbose = 0;
|
ep._verbose = 0;
|
||||||
@ -1685,7 +1686,7 @@ void CPPPreprocessor::
|
|||||||
handle_if_directive(const string &args, const YYLTYPE &loc) {
|
handle_if_directive(const string &args, const YYLTYPE &loc) {
|
||||||
// When expanding manifests, we should replace unknown macros with 0.
|
// When expanding manifests, we should replace unknown macros with 0.
|
||||||
string expr = args;
|
string expr = args;
|
||||||
expand_manifests(expr, _manifests, true);
|
expand_manifests(expr, true);
|
||||||
|
|
||||||
int expression_result = 0;
|
int expression_result = 0;
|
||||||
CPPExpressionParser ep(current_scope, global_scope);
|
CPPExpressionParser ep(current_scope, global_scope);
|
||||||
@ -1730,7 +1731,7 @@ handle_include_directive(const string &args, const YYLTYPE &loc) {
|
|||||||
// filter out quotes and angle brackets properly, we'll only expand
|
// filter out quotes and angle brackets properly, we'll only expand
|
||||||
// manifests if we don't begin with a quote or bracket.
|
// manifests if we don't begin with a quote or bracket.
|
||||||
if (!expr.empty() && (expr[0] != '"' && expr[0] != '<')) {
|
if (!expr.empty() && (expr[0] != '"' && expr[0] != '<')) {
|
||||||
expand_manifests(expr, _manifests, false);
|
expand_manifests(expr, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!expr.empty()) {
|
if (!expr.empty()) {
|
||||||
@ -2332,17 +2333,17 @@ expand_manifest(const CPPManifest *manifest, const YYLTYPE &loc) {
|
|||||||
manifest->_variadic_param, args);
|
manifest->_variadic_param, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make a copy of the manifests, without the ones we're supposed to ignore.
|
// Keep track of the manifests we're supposed to ignore.
|
||||||
Manifests manifests = _manifests;
|
CPPManifest::Ignores ignores;
|
||||||
manifests.erase(manifest->_name);
|
ignores.insert(manifest);
|
||||||
|
|
||||||
for (const InputFile &infile : _files) {
|
for (const InputFile &infile : _files) {
|
||||||
if (infile._ignore_manifest) {
|
if (infile._ignore_manifest) {
|
||||||
manifests.erase(infile._manifest->_name);
|
ignores.insert(infile._manifest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string expanded = " " + manifest->expand(args, manifests, false) + " ";
|
string expanded = " " + manifest->expand(args, false, ignores) + " ";
|
||||||
push_expansion(expanded, manifest, loc);
|
push_expansion(expanded, manifest, loc);
|
||||||
|
|
||||||
#ifdef CPP_VERBOSE_LEX
|
#ifdef CPP_VERBOSE_LEX
|
||||||
@ -2575,7 +2576,7 @@ expand_has_include_function(string &expr, size_t q, size_t &p) const {
|
|||||||
// Only expand if we've encountered unquoted identifier-valid characters,
|
// Only expand if we've encountered unquoted identifier-valid characters,
|
||||||
// to be on the safe side.
|
// to be on the safe side.
|
||||||
if (needs_expansion) {
|
if (needs_expansion) {
|
||||||
expand_manifests(inc, _manifests, false);
|
expand_manifests(inc, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Filename filename;
|
Filename filename;
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
class CPPScope;
|
class CPPScope;
|
||||||
class CPPTemplateParameterList;
|
class CPPTemplateParameterList;
|
||||||
@ -71,7 +72,7 @@ public:
|
|||||||
int get_warning_count() const;
|
int get_warning_count() const;
|
||||||
int get_error_count() const;
|
int get_error_count() const;
|
||||||
|
|
||||||
typedef CPPManifest::Manifests Manifests;
|
typedef std::unordered_map<std::string, CPPManifest *> Manifests;
|
||||||
Manifests _manifests;
|
Manifests _manifests;
|
||||||
|
|
||||||
typedef std::vector<CPPManifest *> ManifestStack;
|
typedef std::vector<CPPManifest *> ManifestStack;
|
||||||
@ -119,8 +120,8 @@ protected:
|
|||||||
const YYLTYPE &loc);
|
const YYLTYPE &loc);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void expand_manifests(std::string &expr, const Manifests &manifests,
|
void expand_manifests(std::string &expr, bool expand_undefined = false,
|
||||||
bool expand_undefined = false) const;
|
const CPPManifest::Ignores &ignores = CPPManifest::Ignores()) const;
|
||||||
CPPExpression *parse_expr(const std::string &expr, CPPScope *current_scope,
|
CPPExpression *parse_expr(const std::string &expr, CPPScope *current_scope,
|
||||||
CPPScope *global_scope, const YYLTYPE &loc);
|
CPPScope *global_scope, const YYLTYPE &loc);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user