वर्बोज़ प्रश्न के लिए खेद है, लेकिन मुझे इसे स्पष्ट करने के लिए कोई और तरीका नहीं दिख रहा है। मैं सी ++ हेडर फ़ाइलों को SWIG इंटरफ़ेस फ़ाइलों में बदलने के लिए एक टूल लिख रहा हूं ताकि आगे बढ़ने के लिए स्टार्टर के रूप में।क्लैंग के साथ नामांकन पार्सिंग: एएसटी अंतर जब किसी अन्य स्रोत फ़ाइल में हेडर समेत या सीधे इसे पार्सिंग
ऐसा करने की प्रक्रिया में, मैंने क्लैंग (v3.0) द्वारा कुछ अजीब व्यवहार देखा है। यदि मैं हेडर फ़ाइल को पार्स करता हूं तो मुझे एक अलग फ़ाइल एएसटी मिलती है, अगर मैं एक स्रोत फ़ाइल को पार्स करता हूं जिसमें हेडर शामिल है।
चित्रांकन के लिए, यहाँ कुछ नमूना स्रोत फ़ाइलें हैं:
स्रोत फ़ाइल:
// example.cpp: Test case for nsbug.py
//
#include "example.h"
हैडर:
// example.h: Test case for nsbug.py
//
namespace Geom {
struct Location
{
double x, y;
};
class Shape
{
public:
Shape();
void set_location(const Location &where)
{
m_pos = where;
};
const Location &get_location() const
// Draw it...
virtual void draw() const = 0;
protected:
Location m_pos;
};
class Circle : public Shape
{
Circle();
virtual void draw() const;
};
} // namespace Geom
मैं निम्नलिखित पायथन कोड का उपयोग किया है यह पार्स करने के लिए और एएसटी डंप करें:
# Usage: python nsbug.py <file>
import sys
import clang.cindex
def indent(level):
""" Indentation string for pretty-printing
"""
return ' '*level
def output_cursor(cursor, level):
""" Low level cursor output
"""
spelling = ''
displayname = ''
if cursor.spelling:
spelling = cursor.spelling
if cursor.displayname:
displayname = cursor.displayname
kind = cursor.kind;
print indent(level) + spelling, '<' + str(kind) + '>'
print indent(level+1) + '"' + displayname + '"'
def output_cursor_and_children(cursor, level=0):
""" Output this cursor and its children with minimal formatting.
"""
output_cursor(cursor, level)
if cursor.kind.is_reference():
print indent(level) + 'reference to:'
output_cursor(clang.cindex.Cursor_ref(cursor), level+1)
# Recurse for children of this cursor
has_children = False;
for c in cursor.get_children():
if not has_children:
print indent(level) + '{'
has_children = True
output_cursor_and_children(c, level+1)
if has_children:
print indent(level) + '}'
index = clang.cindex.Index.create()
tu = index.parse(sys.argv[1], options=1)
output_cursor_and_children(tu.cursor)
जब मैं example.cpp मैं (सही ढंग से मुझे लगता है कि) पर इस चलाएँ:
<CursorKind.TRANSLATION_UNIT>
"example.cpp"
{
(Deleted lots of clang-generated declarations such as __VERSION__)
Geom <CursorKind.NAMESPACE>
"Geom"
{
Location <CursorKind.STRUCT_DECL>
"Location"
{
x <CursorKind.FIELD_DECL>
"x"
y <CursorKind.FIELD_DECL>
"y"
}
Shape <CursorKind.CLASS_DECL>
"Shape"
{
<CursorKind.CXX_ACCESS_SPEC_DECL>
""
<CursorKind.CXX_ACCESS_SPEC_DECL>
""
Shape <CursorKind.CONSTRUCTOR>
"Shape()"
set_location <CursorKind.CXX_METHOD>
"set_location(const Geom::Location &)"
{
where <CursorKind.PARM_DECL>
"where"
{
<CursorKind.TYPE_REF>
"struct Geom::Location"
reference to:
Location <CursorKind.STRUCT_DECL>
"Location"
}
<CursorKind.COMPOUND_STMT>
""
{
<CursorKind.CALL_EXPR>
"operator="
{
<CursorKind.MEMBER_REF_EXPR>
"m_pos"
<CursorKind.UNEXPOSED_EXPR>
"operator="
{
<CursorKind.DECL_REF_EXPR>
"operator="
}
<CursorKind.DECL_REF_EXPR>
"where"
}
}
}
get_location <CursorKind.CXX_METHOD>
"get_location()"
{
<CursorKind.TYPE_REF>
"struct Geom::Location"
reference to:
Location <CursorKind.STRUCT_DECL>
"Location"
}
<CursorKind.CXX_ACCESS_SPEC_DECL>
""
<CursorKind.CXX_ACCESS_SPEC_DECL>
""
m_pos <CursorKind.FIELD_DECL>
"m_pos"
{
<CursorKind.TYPE_REF>
"struct Geom::Location"
reference to:
Location <CursorKind.STRUCT_DECL>
"Location"
}
}
Circle <CursorKind.CLASS_DECL>
"Circle"
{
<CursorKind.CXX_BASE_SPECIFIER>
"class Geom::Shape"
reference to:
Shape <CursorKind.CLASS_DECL>
"Shape"
{
<CursorKind.TYPE_REF>
"class Geom::Shape"
reference to:
Shape <CursorKind.CLASS_DECL>
"Shape"
}
Circle <CursorKind.CONSTRUCTOR>
"Circle()"
draw <CursorKind.CXX_METHOD>
"draw()"
}
}
}
लेकिन जब मैं python nsbug.py example.py
के साथ हेडर फाइल पर यह कोशिश मैं सिर्फ मिलती है:
<CursorKind.TRANSLATION_UNIT>
"example.h"
{
(deleted lots of clang-generated definitions such as __VERSION__)
Geom <CursorKind.VAR_DECL>
"Geom"
}
एएसटी में Geom
नाम स्थान VAR_DECL के रूप में क्यों है? प्रीप्रोसेसर कर्सर को छोड़कर, मुझे कोई फर्क नहीं पड़ता।
कार्य-आसपास स्पष्ट है - बस मेमोरी में एक अस्थायी फ़ाइल बनाएं जिसमें हेडर शामिल है - लेकिन यह बहुत संतोषजनक नहीं है। क्या कोई मुझे प्रबुद्ध कर सकता है?
gremlins आदमी। वे हर जगह हैं। –