mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-29 08:15:18 -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();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
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
|
||||
* its extension. That is, returns true if the filename ends in .c, .C, .cc,
|
||||
|
@ -34,9 +34,6 @@ public:
|
||||
CPPFile(const Filename &filename = "",
|
||||
const Filename &filename_as_referenced = "",
|
||||
Source source = S_none);
|
||||
CPPFile(const CPPFile ©);
|
||||
void operator = (const CPPFile ©);
|
||||
~CPPFile();
|
||||
|
||||
bool is_c_or_i_file() const;
|
||||
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::
|
||||
expand(const vector_string &args, const Manifests &manifests, bool expand_undefined) const {
|
||||
return r_expand(_expansion, args, manifests, expand_undefined);
|
||||
expand(const vector_string &args, bool expand_undefined, const Ignores &ignores) const {
|
||||
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::
|
||||
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;
|
||||
|
||||
for (const ExpansionNode &node : expansion) {
|
||||
@ -631,7 +631,7 @@ r_expand(const Expansion &expansion, const vector_string &args,
|
||||
}
|
||||
|
||||
if (node._expand) {
|
||||
_parser.expand_manifests(subst, manifests, expand_undefined);
|
||||
_parser.expand_manifests(subst, expand_undefined, ignores);
|
||||
}
|
||||
|
||||
if (!subst.empty()) {
|
||||
@ -654,7 +654,7 @@ r_expand(const Expansion &expansion, const vector_string &args,
|
||||
if (!node._nested.empty()) {
|
||||
string nested_result;
|
||||
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) {
|
||||
nested_result = stringify(nested_result);
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "cppBisonDefs.h"
|
||||
|
||||
#include "vector_string.h"
|
||||
#include <unordered_set>
|
||||
|
||||
class CPPExpression;
|
||||
class CPPType;
|
||||
@ -30,7 +31,7 @@ class CPPType;
|
||||
*/
|
||||
class CPPManifest {
|
||||
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 ¯o, const std::string &definition);
|
||||
@ -39,8 +40,8 @@ public:
|
||||
static std::string stringify(const std::string &source);
|
||||
void extract_args(vector_string &args, const std::string &expr, size_t &p) const;
|
||||
std::string expand(const vector_string &args = vector_string(),
|
||||
const Manifests &manifests = Manifests(),
|
||||
bool expand_undefined = false) const;
|
||||
bool expand_undefined = false,
|
||||
const Ignores &ignores = Ignores()) const;
|
||||
|
||||
|
||||
CPPType *determine_type() const;
|
||||
@ -86,7 +87,7 @@ private:
|
||||
const vector_string ¶meter_names);
|
||||
|
||||
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;
|
||||
};
|
||||
|
@ -902,7 +902,8 @@ push_expansion(const string &input, const CPPManifest *manifest, const YYLTYPE &
|
||||
* Given a string, expand all manifests within the string.
|
||||
*/
|
||||
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;
|
||||
while (p < expr.size()) {
|
||||
if (isalpha(expr[p]) || expr[p] == '_') {
|
||||
@ -925,8 +926,8 @@ expand_manifests(string &expr, const Manifests &manifests, bool expand_undefined
|
||||
}
|
||||
else {
|
||||
// Is it a manifest?
|
||||
Manifests::const_iterator mi = manifests.find(ident);
|
||||
if (mi != manifests.end()) {
|
||||
Manifests::const_iterator mi = _manifests.find(ident);
|
||||
if (mi != _manifests.end() && ignores.count((*mi).second) == 0) {
|
||||
const CPPManifest *manifest = (*mi).second;
|
||||
vector_string args;
|
||||
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
|
||||
// result, to prevent recursion.
|
||||
Manifests nested_manifests(manifests);
|
||||
nested_manifests.erase((*mi).first);
|
||||
CPPManifest::Ignores nested_ignores(ignores);
|
||||
nested_ignores.insert(manifest);
|
||||
|
||||
string result = manifest->expand(args);
|
||||
expand_manifests(result, nested_manifests, expand_undefined);
|
||||
string result = manifest->expand(args, expand_undefined, nested_ignores);
|
||||
expand_manifests(result, expand_undefined, nested_ignores);
|
||||
|
||||
expr = expr.substr(0, q) + result + expr.substr(p);
|
||||
p = q + result.size();
|
||||
@ -1008,7 +1009,7 @@ CPPExpression *CPPPreprocessor::
|
||||
parse_expr(const string &input_expr, CPPScope *current_scope,
|
||||
CPPScope *global_scope, const YYLTYPE &loc) {
|
||||
string expr = input_expr;
|
||||
expand_manifests(expr, _manifests, false);
|
||||
expand_manifests(expr, false);
|
||||
|
||||
CPPExpressionParser ep(current_scope, global_scope);
|
||||
ep._verbose = 0;
|
||||
@ -1685,7 +1686,7 @@ void CPPPreprocessor::
|
||||
handle_if_directive(const string &args, const YYLTYPE &loc) {
|
||||
// When expanding manifests, we should replace unknown macros with 0.
|
||||
string expr = args;
|
||||
expand_manifests(expr, _manifests, true);
|
||||
expand_manifests(expr, true);
|
||||
|
||||
int expression_result = 0;
|
||||
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
|
||||
// manifests if we don't begin with a quote or bracket.
|
||||
if (!expr.empty() && (expr[0] != '"' && expr[0] != '<')) {
|
||||
expand_manifests(expr, _manifests, false);
|
||||
expand_manifests(expr, false);
|
||||
}
|
||||
|
||||
if (!expr.empty()) {
|
||||
@ -2332,17 +2333,17 @@ expand_manifest(const CPPManifest *manifest, const YYLTYPE &loc) {
|
||||
manifest->_variadic_param, args);
|
||||
}
|
||||
|
||||
// Make a copy of the manifests, without the ones we're supposed to ignore.
|
||||
Manifests manifests = _manifests;
|
||||
manifests.erase(manifest->_name);
|
||||
// Keep track of the manifests we're supposed to ignore.
|
||||
CPPManifest::Ignores ignores;
|
||||
ignores.insert(manifest);
|
||||
|
||||
for (const InputFile &infile : _files) {
|
||||
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);
|
||||
|
||||
#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,
|
||||
// to be on the safe side.
|
||||
if (needs_expansion) {
|
||||
expand_manifests(inc, _manifests, false);
|
||||
expand_manifests(inc, false);
|
||||
}
|
||||
|
||||
Filename filename;
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
class CPPScope;
|
||||
class CPPTemplateParameterList;
|
||||
@ -71,7 +72,7 @@ public:
|
||||
int get_warning_count() const;
|
||||
int get_error_count() const;
|
||||
|
||||
typedef CPPManifest::Manifests Manifests;
|
||||
typedef std::unordered_map<std::string, CPPManifest *> Manifests;
|
||||
Manifests _manifests;
|
||||
|
||||
typedef std::vector<CPPManifest *> ManifestStack;
|
||||
@ -119,8 +120,8 @@ protected:
|
||||
const YYLTYPE &loc);
|
||||
|
||||
public:
|
||||
void expand_manifests(std::string &expr, const Manifests &manifests,
|
||||
bool expand_undefined = false) const;
|
||||
void expand_manifests(std::string &expr, bool expand_undefined = false,
|
||||
const CPPManifest::Ignores &ignores = CPPManifest::Ignores()) const;
|
||||
CPPExpression *parse_expr(const std::string &expr, CPPScope *current_scope,
|
||||
CPPScope *global_scope, const YYLTYPE &loc);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user