在 C++ 中嵌入 Guile 的问题;
我是一名Scheme 程序员,我正在尝试使用Guile 从Bison 规范中的C++ 代码调用Scheme 函数。关于 Guile 和 C 的文档很棒;但是,我还没有找到太多有关 Guile 和 C++ 的相关最新信息。因为每个 C 程序在技术上都是 C++ 程序,所以通过 Guile 从 C++ 调用 Scheme 函数应该很容易。唉,我不是 C/C++ 程序员,所以我希望这里的一些 C++ 专家可以帮助我。以下是我的一些代码:
%{
#include <fstream>
#include <iomanip>
#include <string>
using namespace std;
#include "List.h"
#include "paslex.h"
#include "paspar.h"
#include <libguile.h>
extern "C" {
#include "symtable.h"
}
void yyerror(char* m);
extern ofstream tfs;
extern int line;
extern int col;
extern "C" {
// Create namespace stack and lexical level 0 with built-in types.
SCM namespace_stack;
SCM namespace0;
SCM real_type;
SCM real_type_sym;
SCM integer_type;
SCM integer_type_sym;
// errors begin here
namespace_stack = make_name_stack();
namespace0 = make_namespace();
real_type = make_type_attr(64, 64);
real_type_sym = make_type_sym("real", real_type);
integer_type = make_type_attr(32, 32);
integer_type_sym = make_type_sym("integer", integer_type);
insert_symbol(real_type_sym, namespace0);
insert_symbol(integer_type_sym, namespace0);
push(namespace0, namespace_stack);
}
%}
我的方案代码的包装函数位于 symtable.c 中。使用纯 C 中的这些相同函数效果很好。从 C++ 调用它们会生成以下编译器错误:
paspar.y:33:错误:预期 构造函数、析构函数或类型 '=' 标记之前的转换
...以及第 34 行到第 42 行的类似错误。我在 Ubuntu 10.10 上使用 GCC 4.4.5 和 Guile 1.6.8。我尝试将 libguile.h include 移动到 extern“C”块的内部和外部,但结果是相同的。我确信这是一个新手错误,但我们将不胜感激解决此问题的帮助。如果需要更多信息,请告诉我。我在下面包含了 symtable.h:
// Description: API to translator symbol table, including namespaces,
// namespace stacks, and descriptors.
// Constants used by descriptors.
#define CONSTANT_ID 0
#define FUNCTION_ID 1
#define PROCEDURE_ID 2
#define VARIABLE_ID 3
#define TYPE_SYM_ID 4
#define TYPE_ATTR_ID 5
#define TYPE_ENUM_ID 6
#define TYPE_RANGE_ID 7
#define TYPE_ARRAY_ID 8
#define TYPE_RECORD_ID 9
#define TYPE_POINTER_ID 10
#define TYPE_SET_ID 11
//------------------------------------NAMESPACE STACK--------------------------------------
SCM make_name_stack();
// Create and return a namespace stack.
void push(SCM namspace, SCM stack);
// Places a namespace on the stack.
// @param stack The stack to place value on.
// @param namspace The namespace to place on the stack.
// @return None
SCM pop(SCM stack);
// Returns namespace on top of stack.
// @param stack The stack to return value from.
// @return The namespace on top of stack.
void sremove(SCM stack);
// Removes the top value on stack.
// @param stack The stack to remove top value from.
// @return None
int empty(SCM stack);
// A predicate for determining if a stack is empty.
// @param Stack The stack to test.
// @return 1 if the stack is empty, 0 if it is not.
SCM find_stack_symbol(char* name, SCM stack);
// Finds the symbol descriptor for the given identifier.
// @param name The symbol name.
// @param stack The stack to search.
// @return The symbol descriptor or 0 if the symbol could not be found.
int lexical_level(char* name, SCM stack);
// Find the lexical level of the identifier.
// @param name The symbol name.
// @param stack The stack to search.
// @return The lexical level or -1 if the symbol could not be found.
int current_level(SCM stack);
// Find lexical level of the top namespace.
// @param stack The stack to search.
// @return The lexical level or -1 if stack is empty.
//------------------------------------NAMESPACE--------------------------------------
SCM make_namespace();
// Create and return a namespace.
void insert_symbol(SCM symbol, SCM namspace);
// Insert descriptor into namespace
// @param descriptor The descriptor to insert.
// @param namspace The namespace to insert the descriptor into.
// @return Nothing.
SCM find_symbol(SCM symbol, SCM namspace);
// Search for symbol in target namespace.
// @param symbol The symbol to search for.
// @param namspace The namespace to search for symbol.
// @return A symbol descriptor, or 0 if symbol not found.
int get_lex(SCM namspace);
// Get lexical level of target namespace.
// @param namspace The namespace whose lexical level to get.
// @return Lexical level, or -1 if namespace has not yet been assigned one.
// ------------------------------SYMBOL DESCRIPTORS-------------------------------
SCM make_constant(char* name, SCM type, char* value);
// Makes a constant symbol descriptor.
// @param identifier Name of the constant.
// @param type The constant's type descriptor.
// @param value String representation of the constant.
// @return A constant symbol descriptor.
SCM make_var(char* name, SCM type, double address);
// Makes a variable symbol descriptor.
// @param identifier Name of the variable.
// @param type Address of the variable's type descriptor.
// @param address Starting address of the variable itself.
// @return A variable symbol descriptor.
SCM make_function(char* name, SCM params, double address);
// Makes a function symbol descriptor.
// @param identifier Name of the function.
// @param params A list of function parameters. The first element should
// always be the return type.
// @param address Address of the first function instruction.
// @return A function symbol descriptor.
SCM make_procedure(char* name, SCM params, double address);
// Makes a procedure symbol descriptor.
// @param identifier Name of the procedure.
// @param params A list of procedure parameters. Does not include a return type.
// @param address Address of the first procedure instruction.
// @return A procedure symbol descriptor.
SCM make_type_sym(char* name, SCM type);
// Make a type symbol descriptor.
// @param identifer Name of the type.
// @param type Address of the type's attributes.
// @return A type symbol descriptor.
int get_id(SCM descriptor);
// Return descriptor id.
void get_name(SCM descriptor, char* name);
// Return descriptor name.
// @param descriptor Target descriptor.
// @param name Output parameter for descriptor name.
int get_value(SCM descriptor, char* value);
// Get string representation of a constant symbol descriptor.
// @param descriptor Target descriptor.
// @param value Output parameter for descriptor value.
// @return 0 if not a constant, 1 if a constant.
double get_address(SCM descriptor);
// Get address of descriptor.
// @param descriptor Target descriptor.
// @return address, or -1 if descriptor does not possess an address.
SCM get_params(SCM descriptor);
// Get parameter list of descriptor.
// @param descriptor Target descriptor.
// @return parameter list, or 0 if descriptor does not possess a parameter list.
SCM get_type(SCM descriptor);
// Get type referenced by descriptor.
// @param descriptor Target descriptor.
// @return type, or 0 if descriptor does not reference a type.
int set_type(SCM descriptor, SCM type);
// Set type referenced by descriptor.
// @param descriptor Target descriptor.
// @param type Target type.
// @return 1 if type set successfully, or 0 if it failed.
// -------------------------------TYPE DESCRIPTORS-------------------------------
SCM make_type_attr(double size, int align);
// Make a type symbol attribute descriptor.
// @param size Size of the type in bits.
// @param align Type alignment in bits.
// @return A type attribute descriptor.
SCM make_type_enum(double size, int align, SCM syms);
// Make an enumerated type descriptor.
// @param size Size of the type in bits.
// @param align Alignment of the type in bits.
// @param syms A Scheme list of symbol type descriptors.
// @return An enumerated type descriptor.
SCM make_type_range(double size, int align, SCM low, SCM high);
// Make a ranged type.
// @param size Size of the type in bits.
// @param align Alignment of the type in bits.
// @param low Low value in the range (a symbol descriptor).
// @param high High value in the range (a symbol descriptor).
// @return A ranged type descriptor.
SCM make_type_array(double size, int align, SCM index, SCM element);
// Make an array type.
// @param size Size of the type in bits.
// @param align Alignment of the type in bits.
// @param index The type of allowable index values (a symbol descriptor).
// @param element The type of allowable element values (a symbol descriptor).
// @return An array type descriptor.
SCM make_type_record(double size, int align, SCM vars);
// Make a record type.
// @param size Size of the type in bits.
// @param align Alignment of the type in bits.
// @param vars A Scheme list of variable type descriptors.
// @return A record type descriptor.
SCM make_type_pointer(double size, int align, SCM type);
// Make a pointer type.
// @param size Size of the type in bits.
// @param align Alignment of the type in bits.
// @param type The type pointer is referencing.
// @return A pointer type.
SCM make_type_set(double size, int align, SCM enum_type);
// Make a set type.
// @param size Size of the type in bits.
// @param align Alignment of the type in bits.
// @param enum The enumerated type used by this set.
// @return A set type.
SCM make_type_null();
// Make a null type for use when the descriptor type is not known
// at creation time.
int check_null(SCM type);
// Checks if a type is null.
// Returns 1 if null, or 0 if not null.
double get_size(SCM descriptor);
// Return size of type in bits.
int get_align(SCM descriptor);
// Return alignment of type in bits.
SCM get_vars(SCM descriptor, int* boolean);
// Return variable list from record descriptor.
// @param descriptor Target descriptor.
// @param boolean Output parameter returns 0 if not record descriptor.
// @return A variable list.
SCM get_index(SCM descriptor, int* boolean);
// Return index type from array descriptor.
// @param descriptor Target descriptor.
// @param boolean Output parameter returns 0 if not array descriptor.
// @return Index type.
SCM get_element(SCM descriptor, int* boolean);
// Return element type from array descriptor.
// @param descriptor Target descriptor.
// @param boolean Output parameter returns 0 if not array descriptor.
// @return Element type.
SCM get_low(SCM descriptor, int* boolean);
// Return low type from range descriptor.
// @param descriptor Target descriptor.
// @param boolean Output parameter returns 0 if not range descriptor.
// @return Low type.
SCM get_high(SCM descriptor, int* boolean);
// Return high type from range descriptor.
// @param descriptor Target descriptor.
// @param boolean Output parameter returns 0 if not range descriptor.
// @return High type.
SCM get_syms(SCM descriptor, int* boolean);
// Return symbol list from enumerated descriptor.
// @param descriptor Target descriptor.
// @param boolean Output parameter returns 0 if not enumerated descriptor.
// @return Symbol list.
I'm a Scheme programmer, and I'm attempting to use Guile to call Scheme functions from C++ code within a Bison specification. The documentation concerning Guile and C is great; however, I haven't found much relevant, up-to-date information about Guile and C++. Because every C program is technically a C++ program, calling Scheme functions from C++ via Guile should be easy enough. Alas, I'm not a C/C++ programmer, so I was hoping some of the C++ gurus on here could help me out. Here is some of my code:
%{
#include <fstream>
#include <iomanip>
#include <string>
using namespace std;
#include "List.h"
#include "paslex.h"
#include "paspar.h"
#include <libguile.h>
extern "C" {
#include "symtable.h"
}
void yyerror(char* m);
extern ofstream tfs;
extern int line;
extern int col;
extern "C" {
// Create namespace stack and lexical level 0 with built-in types.
SCM namespace_stack;
SCM namespace0;
SCM real_type;
SCM real_type_sym;
SCM integer_type;
SCM integer_type_sym;
// errors begin here
namespace_stack = make_name_stack();
namespace0 = make_namespace();
real_type = make_type_attr(64, 64);
real_type_sym = make_type_sym("real", real_type);
integer_type = make_type_attr(32, 32);
integer_type_sym = make_type_sym("integer", integer_type);
insert_symbol(real_type_sym, namespace0);
insert_symbol(integer_type_sym, namespace0);
push(namespace0, namespace_stack);
}
%}
My wrapper functions for the Scheme code are in symtable.c. Using these same functions from pure C works just fine. Calling them from C++ generates the following compiler error:
paspar.y:33: error: expected
constructor, destructor, or type
conversion before ‘=’ token
...and a similar error for lines 34 through 42. I'm using GCC 4.4.5 and Guile 1.6.8 on Ubuntu 10.10. I've tried moving the libguile.h include inside and outside the extern "C" block, but the result is the same. I'm sure this is a newbie mistake, but help with this problem would be greatly appreciated. Let me know if more information is needed. I've included symtable.h below:
// Description: API to translator symbol table, including namespaces,
// namespace stacks, and descriptors.
// Constants used by descriptors.
#define CONSTANT_ID 0
#define FUNCTION_ID 1
#define PROCEDURE_ID 2
#define VARIABLE_ID 3
#define TYPE_SYM_ID 4
#define TYPE_ATTR_ID 5
#define TYPE_ENUM_ID 6
#define TYPE_RANGE_ID 7
#define TYPE_ARRAY_ID 8
#define TYPE_RECORD_ID 9
#define TYPE_POINTER_ID 10
#define TYPE_SET_ID 11
//------------------------------------NAMESPACE STACK--------------------------------------
SCM make_name_stack();
// Create and return a namespace stack.
void push(SCM namspace, SCM stack);
// Places a namespace on the stack.
// @param stack The stack to place value on.
// @param namspace The namespace to place on the stack.
// @return None
SCM pop(SCM stack);
// Returns namespace on top of stack.
// @param stack The stack to return value from.
// @return The namespace on top of stack.
void sremove(SCM stack);
// Removes the top value on stack.
// @param stack The stack to remove top value from.
// @return None
int empty(SCM stack);
// A predicate for determining if a stack is empty.
// @param Stack The stack to test.
// @return 1 if the stack is empty, 0 if it is not.
SCM find_stack_symbol(char* name, SCM stack);
// Finds the symbol descriptor for the given identifier.
// @param name The symbol name.
// @param stack The stack to search.
// @return The symbol descriptor or 0 if the symbol could not be found.
int lexical_level(char* name, SCM stack);
// Find the lexical level of the identifier.
// @param name The symbol name.
// @param stack The stack to search.
// @return The lexical level or -1 if the symbol could not be found.
int current_level(SCM stack);
// Find lexical level of the top namespace.
// @param stack The stack to search.
// @return The lexical level or -1 if stack is empty.
//------------------------------------NAMESPACE--------------------------------------
SCM make_namespace();
// Create and return a namespace.
void insert_symbol(SCM symbol, SCM namspace);
// Insert descriptor into namespace
// @param descriptor The descriptor to insert.
// @param namspace The namespace to insert the descriptor into.
// @return Nothing.
SCM find_symbol(SCM symbol, SCM namspace);
// Search for symbol in target namespace.
// @param symbol The symbol to search for.
// @param namspace The namespace to search for symbol.
// @return A symbol descriptor, or 0 if symbol not found.
int get_lex(SCM namspace);
// Get lexical level of target namespace.
// @param namspace The namespace whose lexical level to get.
// @return Lexical level, or -1 if namespace has not yet been assigned one.
// ------------------------------SYMBOL DESCRIPTORS-------------------------------
SCM make_constant(char* name, SCM type, char* value);
// Makes a constant symbol descriptor.
// @param identifier Name of the constant.
// @param type The constant's type descriptor.
// @param value String representation of the constant.
// @return A constant symbol descriptor.
SCM make_var(char* name, SCM type, double address);
// Makes a variable symbol descriptor.
// @param identifier Name of the variable.
// @param type Address of the variable's type descriptor.
// @param address Starting address of the variable itself.
// @return A variable symbol descriptor.
SCM make_function(char* name, SCM params, double address);
// Makes a function symbol descriptor.
// @param identifier Name of the function.
// @param params A list of function parameters. The first element should
// always be the return type.
// @param address Address of the first function instruction.
// @return A function symbol descriptor.
SCM make_procedure(char* name, SCM params, double address);
// Makes a procedure symbol descriptor.
// @param identifier Name of the procedure.
// @param params A list of procedure parameters. Does not include a return type.
// @param address Address of the first procedure instruction.
// @return A procedure symbol descriptor.
SCM make_type_sym(char* name, SCM type);
// Make a type symbol descriptor.
// @param identifer Name of the type.
// @param type Address of the type's attributes.
// @return A type symbol descriptor.
int get_id(SCM descriptor);
// Return descriptor id.
void get_name(SCM descriptor, char* name);
// Return descriptor name.
// @param descriptor Target descriptor.
// @param name Output parameter for descriptor name.
int get_value(SCM descriptor, char* value);
// Get string representation of a constant symbol descriptor.
// @param descriptor Target descriptor.
// @param value Output parameter for descriptor value.
// @return 0 if not a constant, 1 if a constant.
double get_address(SCM descriptor);
// Get address of descriptor.
// @param descriptor Target descriptor.
// @return address, or -1 if descriptor does not possess an address.
SCM get_params(SCM descriptor);
// Get parameter list of descriptor.
// @param descriptor Target descriptor.
// @return parameter list, or 0 if descriptor does not possess a parameter list.
SCM get_type(SCM descriptor);
// Get type referenced by descriptor.
// @param descriptor Target descriptor.
// @return type, or 0 if descriptor does not reference a type.
int set_type(SCM descriptor, SCM type);
// Set type referenced by descriptor.
// @param descriptor Target descriptor.
// @param type Target type.
// @return 1 if type set successfully, or 0 if it failed.
// -------------------------------TYPE DESCRIPTORS-------------------------------
SCM make_type_attr(double size, int align);
// Make a type symbol attribute descriptor.
// @param size Size of the type in bits.
// @param align Type alignment in bits.
// @return A type attribute descriptor.
SCM make_type_enum(double size, int align, SCM syms);
// Make an enumerated type descriptor.
// @param size Size of the type in bits.
// @param align Alignment of the type in bits.
// @param syms A Scheme list of symbol type descriptors.
// @return An enumerated type descriptor.
SCM make_type_range(double size, int align, SCM low, SCM high);
// Make a ranged type.
// @param size Size of the type in bits.
// @param align Alignment of the type in bits.
// @param low Low value in the range (a symbol descriptor).
// @param high High value in the range (a symbol descriptor).
// @return A ranged type descriptor.
SCM make_type_array(double size, int align, SCM index, SCM element);
// Make an array type.
// @param size Size of the type in bits.
// @param align Alignment of the type in bits.
// @param index The type of allowable index values (a symbol descriptor).
// @param element The type of allowable element values (a symbol descriptor).
// @return An array type descriptor.
SCM make_type_record(double size, int align, SCM vars);
// Make a record type.
// @param size Size of the type in bits.
// @param align Alignment of the type in bits.
// @param vars A Scheme list of variable type descriptors.
// @return A record type descriptor.
SCM make_type_pointer(double size, int align, SCM type);
// Make a pointer type.
// @param size Size of the type in bits.
// @param align Alignment of the type in bits.
// @param type The type pointer is referencing.
// @return A pointer type.
SCM make_type_set(double size, int align, SCM enum_type);
// Make a set type.
// @param size Size of the type in bits.
// @param align Alignment of the type in bits.
// @param enum The enumerated type used by this set.
// @return A set type.
SCM make_type_null();
// Make a null type for use when the descriptor type is not known
// at creation time.
int check_null(SCM type);
// Checks if a type is null.
// Returns 1 if null, or 0 if not null.
double get_size(SCM descriptor);
// Return size of type in bits.
int get_align(SCM descriptor);
// Return alignment of type in bits.
SCM get_vars(SCM descriptor, int* boolean);
// Return variable list from record descriptor.
// @param descriptor Target descriptor.
// @param boolean Output parameter returns 0 if not record descriptor.
// @return A variable list.
SCM get_index(SCM descriptor, int* boolean);
// Return index type from array descriptor.
// @param descriptor Target descriptor.
// @param boolean Output parameter returns 0 if not array descriptor.
// @return Index type.
SCM get_element(SCM descriptor, int* boolean);
// Return element type from array descriptor.
// @param descriptor Target descriptor.
// @param boolean Output parameter returns 0 if not array descriptor.
// @return Element type.
SCM get_low(SCM descriptor, int* boolean);
// Return low type from range descriptor.
// @param descriptor Target descriptor.
// @param boolean Output parameter returns 0 if not range descriptor.
// @return Low type.
SCM get_high(SCM descriptor, int* boolean);
// Return high type from range descriptor.
// @param descriptor Target descriptor.
// @param boolean Output parameter returns 0 if not range descriptor.
// @return High type.
SCM get_syms(SCM descriptor, int* boolean);
// Return symbol list from enumerated descriptor.
// @param descriptor Target descriptor.
// @param boolean Output parameter returns 0 if not enumerated descriptor.
// @return Symbol list.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您试图在函数之外执行工作,这在 C 中是不允许的,并且在 C++ 中也有很大的限制。以 开头的语句
不应位于顶层,而应位于函数内部(例如,
main
)。顺便说一句,为什么要使用extern "C"
块?You're attempting to perform work outside a function, which is not allowed in C and only with great limitations in C++. The statements starting with
should not be at top-level, but inside a function (e.g.,
main
). Why do you use anextern "C"
block, btw.?