我目前正致力于使用C ++创建一个小型编译器。我已经定义了以下对象:
struct ValueNode
{
std::string name;
int value;
};
struct StatementNode
{
StatementType type;
union
{
struct AssignmentStatement * assign_stmt;
struct PrintStatement * print_stmt;
struct IfStatement * if_stmt;
struct GotoStatement * goto_stmt;
};
struct StatementNode * next; // next statement in the list or NULL
};
我已经定义了一系列与语言中不同类型语句相关的函数。其中一个函数称为parse_assignment_stmt()。我正在经历的分段错误发生在此函数中,在尝试为最近分配的内存分配值之后立即发生。这是函数:
struct StatementNode* parse_assign_stmt() {
//Object to be returned. Holds an object representing a statement
//made within the input program.
struct StatementNode* st = (struct StatementNode*)malloc(sizeof(struct StatementNode));
st->type = ASSIGN_STMT;
//First token should be an ID. Represents memory location we are assigning to.
Token tok = lexer->GetToken();
if(tok.token_type == ID) {
//Second token in an assignment should be an equal sign
Token tok2 = lexer->GetToken();
if (tok2.token_type == EQUAL) {
//This function reads the next token, makes sure it is of type NUM or ID, then creates and returns a ValueNode containing the relevant value.
struct ValueNode* rhs1 = parse_primary();
Token tok3 = lexer->GetToken();
//Assignment format for this logical branch: "x = 5;"
if(tok3.token_type == SEMICOLON) {
//first type
//Allocate memory for objects needed to build StatementNode st
struct AssignmentStatement* assign_stmt = (struct AssignmentStatement*)malloc(sizeof(struct AssignmentStatement));
struct ValueNode* lhs = (struct ValueNode*)malloc( sizeof(struct ValueNode));
printf("Name: %s, Value: %d\n", lhs->name.c_str(), lhs->value);
//PROBLEM ARISES HERE***
//lhs->name = tok.lexeme;
//return the proper structure
return st;
}
else if(tok3.token_type == PLUS || tok3.token_type == MINUS || tok3.token_type == DIV || tok3.token_type == MULT) {
//second type
//TODO
}
else {
printf("Syntax error. Semicolon or operator expected after first primary on RHS of assignment.");
exit(1);
}
}
else {
//not of proper form
printf("Syntax error. EQUAL expected after LHS of assignment.");
exit(1);
}
}
else {
//Not of proper form. Syntax error
printf("Syntax error. ID expected at beginning of assignment.");
exit(1);
}
}
基本上,我为新的ValueNode分配内存以创建变量lhs。我正在立即打印出名称和值字段,以确保没有任何内容。在我的编译器输出中(顺便说一下,我使用g ++),它告诉我名称是(null),值是0,这是预期的。一旦我取消注释该行
lhs->name = tok.lexeme;
我遇到了分段错误。在这一点上,我不知道会出现什么问题。我正在创建变量,使用malloc为该位置分配内存,确保没有存储任何内容,然后立即尝试写入值。它总是给我一个分段错误。
这是通过stdin提供给程序的输入程序(.txt文件)。
i;
{
i = 42 ;
print i;
}
我尝试使用calloc()代替,因为这应该确保在返回指针之前清除内存,但这并没有改变任何东西。任何建议都会很精彩。谢谢!
答案 0 :(得分:0)
如果问题出现在该行中:
lhs->name = tok.lexeme;
然后我保证问题在于lhs
或tok.lexeme
。
在此之前,您似乎已确认lhs
可以使用:
printf("Name: %s, Value: %d\n", lhs->name.c_str(), lhs->value);
那么令牌结构出现问题的可能性就会大大增加。
但是,我们不应该猜测,您应该能够将代码加载到一个好的调试器(甚至是gdb
,在一个紧凑的(a)中,在违规行设置一个断点,实际上看变量以查看它们是否符合预期。或者,至少在尝试使用它之前打印出更多东西。
除此之外:在大学教授的第一个课程不是调试101,这一直是我的一个小问题。这是我教儿子一开始的第一个的事情做Python开发。
(a) Pax ducks for cover: - )
答案 1 :(得分:0)
经过进一步研究,我发现在为我的ValueNode对象分配内存(使用malloc())时(由于某种原因,只有这些),malloc()返回一个指向无法访问的内存的指针。尝试打印我的ValueNode结构时在gdb中收到的错误是:
{name =<'错误读取变量:无法访问地址0xfffffffe8的内存>,值= 42}
不幸的是,我无法使用malloc()找到为此对象分配内存的方法。然而,我设法实现的解决方法是在ValueNode的结构定义中创建构造函数,然后使用" new"创建对象并为我分配内存,而不是试图强制malloc()工作。回想起来,我可能应该使用这种比malloc()更简单的方法来开始。