【问题标题】:Segmentation fault from Lemon-generated parser in C++C++ 中 Lemon 生成的解析器的分段错误
【发布时间】:2023-03-22 21:21:01
【问题描述】:

我正在尝试弄清楚 Lemon 解析器生成器,所以我写了一个小测试来帮助自己完全理解。 文件生成没有问题,编译器没有抱怨,但是当我尝试运行它时,我得到一个分段错误。 我做错了什么?

lexicon.l:

%{
#include "grammar.h"
%}

%option noyywrap

%%

[A-Za-z_][A-Za-z0-9]*   return IDENTIFIER;
\".*\"                  return STRING;
[0-9]+                  return NUMBER;
"="                     return EQUALS;
\n                      return NEWLINE;
%%

语法.y:

%include {
#include <vector>
#include <iostream>
#include <cassert>
#include <sstream>
#include "AST.h"
}

%token_type {char *}
%extra_argument {std::vector<Identifier>& identifiers}

start ::= assignments. {
    std::cout << "start resolved" << std::endl;
}

assignments ::= assignment.
{
    std::cout << "assignments resolved" << std::endl;
}
assignments ::= assignments NEWLINE assignment.

assignment ::= IDENTIFIER(id) EQUALS STRING(str).
{
    std::cout << "I get here too" << std::endl;
    identifiers.push_back(Identifier(id, str));
}

assignment ::= IDENTIFIER(id) EQUALS NUMBER(num).
{
    std::stringstream ss;
    ss << num;
    identifiers.push_back(Identifier(id, ss.str()));
}

main.cpp:

#include "AST.h"

using namespace std;

void* ParseAlloc(void* (*allocProc)(size_t));
void Parse(void*, int, char *, vector<Identifier>&);
void ParseFree(void*, void(*freeProc)(void*));

int yylex();
extern char * yytext;

int main() {
    vector<Identifier> identifiers;
    void* parser = ParseAlloc(malloc);
    cout << "Line 20" << endl;
    while (int lexcode = yylex()) {
        cout << "Getting in the loop: " << yytext << endl;
        Parse(parser, lexcode, yytext, identifiers);
    }
    Parse(parser, 0, NULL, identifiers);
    cout << "Line 25" << endl;
    ParseFree(parser, free);

    return 0;
}

AST.h:

#include <string>
#include <iostream>

class Identifier {
    std::string name;
    std::string value;
public:
    Identifier(std::string _name, std::string _value)
    : name(_name),
      value(_value) {
        std::cout << "Initializing " << name << " as " << value << std::endl;
    }

    std::string getName();
    std::string getValue();
    void setValue(std::string _value);
};

AST.cpp:

#include "AST.h"

std::string Identifier::getName() {
    return name;
}

std::string Identifier::getValue() {
    return value;
}

void Identifier::setValue(std::string _value) {
    value = _value;
}

最后是测试输入:

alpha = "Hello"
beta = "World"
gamma = 15

还有输出:

mikidep@mikidep-virtual:~/Scrivania/bison test$ cat text | ./parserLine 20
Getting in the loop: alpha
Segmentation Fault

【问题讨论】:

    标签: c++ lemon


    【解决方案1】:

    使用指针来表示标识符的std::vector。我不确定它是如何在编译错误中发生的,但在代码的某处它会尝试归因于std::vector&lt;Identifier&gt;&amp; 类型的变量。如果我没记错的话,你不能对引用进行归因。

    所以,更改为 std::vector&lt;Identifier&gt;* 可以解决您的问题。

    【讨论】:

    • 从调试日志中可以看出,甚至没有达到使用标识符向量的点。
    • @Glaedr 尝试执行yypParser-&gt;identifiers = identifiers 时出现段错误,左侧的类型为std::vector&lt;Identifier&gt;&amp;,此引用未初始化,因此它指向NULL。它将以std::vector&lt;Identifier, std::allocator&lt;Identifier&gt; &gt;::operator= (this=0x0, __x=std::vector of length 0, capacity 0) 结尾,请查看this=0x0。我用 gdb 来做答案,我不只是猜测。
    • 所以奇怪的行为是由于分配时采用不同的方法指针和引用,后者受到运算符重载的影响?
    猜你喜欢
    • 2016-01-21
    • 1970-01-01
    • 2012-08-03
    • 1970-01-01
    • 1970-01-01
    • 2015-08-02
    • 1970-01-01
    • 1970-01-01
    • 2011-07-17
    相关资源
    最近更新 更多