1

我是一名 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);
 }

%}

我的 Scheme 代码的包装函数在 symtable.c 中。在纯 C 中使用这些相同的函数就可以了。从 C++ 调用它们会产生以下编译器错误:

paspar.y:33: 错误: '=' 标记之前的预期构造函数、析构函数或类型转换

...以及第 34 行到第 42 行的类似错误。我在 Ubuntu 10.10 上使用 GCC 4.4.5 和 Guile 1.6.8。我尝试将 libguile.h 包含在 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.
4

1 回答 1

3

您正在尝试在函数之外执行工作,这在 C 中是不允许的,并且仅在 C++ 中存在很大限制。开头的语句

namespace_stack = make_name_stack();

不应位于顶层,而应位于函数内部(例如,main)。顺便说一句,你为什么要使用extern "C"块?

于 2011-02-22T06:34:07.877 回答