c++ - 在另一个文件中使用 lex 生成的源代码

标签 c++ c parsing lex lexical-analysis

我想在我拥有的另一个代码中使用 lex 生成的代码,但我看到的所有示例都是将 main 函数嵌入到 lex 文件中,而不是相反。

是否可以使用(包含)从 lex 生成的 c 文件到其他具有类似内容(不一定相同)的代码中?

#include<something>
int main(){
    Lexer l = Lexer("some string or input file");
    while (l.has_next()){
        Token * token = l.get_next_token();
        //somecode
    }
    //where token is just a simple object to hold the token type and lexeme
    return 0;
}

最佳答案

这就是我要开始的:
注意:这是一个使用C接口(interface)的例子
要使用 C++ 接口(interface),请添加 %option c++ 见下文

测试.lex

IdentPart1      [A-Za-z_]
Identifier      {IdentPart1}[A-Za-z_0-9]*
WHITESPACE      [ \t\r\n]

%option noyywrap

%%

{Identifier}      {return 257;}
{WHITESPACE}      {/* Ignore */}
.                 {return 258;}

%%

// This is the bit you want.
// It is best just to put this at the bottom of the lex file
// By default functions are extern. So you can create a header file with
// these as extern then included that header file in your code (See Lexer.h)
void* setUpBuffer(char const* text)
{
    YY_BUFFER_STATE buffer  = yy_scan_string(text);
    yy_switch_to_buffer(buffer);

    return buffer;
}

void tearDownBuffer(void* buffer)
{
    yy_delete_buffer((YY_BUFFER_STATE)buffer);
}

词法分析器.h

#ifndef LOKI_A_LEXER_H
#define LOKI_A_LEXER_H

#include <string>

extern int   yylex();
extern char* yytext;
extern int   yyleng;

// Here is the interface to the lexer you set up above
extern void* setUpBuffer(char const* text);
extern void  tearDownBuffer(void* buffer);


class Lexer
{
    std::string         token;
    std::string         text;
    void*               buffer;
    public:
    Lexer(std::string const& t)
        : text(t)
    {
        // Use the interface to set up the buffer
        buffer  = setUpBuffer(text.c_str());
    }
    ~Lexer()
    {
        // Tear down your interface
        tearDownBuffer(buffer);
    }
    // Don't use RAW pointers
    // This is only a quick and dirty example.
    bool  nextToken()
    {
        int val = yylex();
        if (val != 0)
        {
            token = std::string(yytext, yyleng);
        }
        return val;
    }
    std::string const& theToken() const {return token;}
};

#endif

main.cpp

#include "Lexer.h"
#include <iostream>

int main()
{
    Lexer l("some string or input file");


    // Did not like your hasToken() interface.
    // Just call nextToken() until it fails.
    while (l.nextToken())
    {
        std::cout << l.theToken() << "\n";
        delete token;
    }
    //where token is just a simple object to hold the token type and lexeme
    return 0;
}

构建

> flext test.lex
> g++ main.cpp  lex.yy.c
> ./a.out
some
string
or
input
file
>

或者,您可以使用 C++ 接口(interface)来 flex(它是实验性的)

测试.lext

%option c++


IdentPart1      [A-Za-z_]
Identifier      {IdentPart1}[A-Za-z_0-9]*
WHITESPACE      [ \t\r\n]

%%

{Identifier}      {return 257;}
{WHITESPACE}      {/* Ignore */}
.                 {return 258;}

%%

// Note this needs to be here
// If you define no yywrap() in the options it gets added to the header file
// which leads to multiple definitions if you are not careful.
int yyFlexLexer::yywrap()   { return 1;}

main.cpp

#include "MyLexer.h"
#include <iostream>
#include <sstream>

int main()
{
    std::istringstream  data("some string or input file");
    yyFlexLexer l(&data, &std::cout);


    while (l.yylex())
    {
        std::cout << std::string(l.YYText(), l.YYLeng()) << "\n";
    }
    //where token is just a simple object to hold the token type and lexeme
    return 0;
}

构建

> flex --header-file=MyLexer.h test.lex
> g++ main.cpp lex.yy.cc
> ./a.out
some
string
or
input
file
>

关于c++ - 在另一个文件中使用 lex 生成的源代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8013755/

相关文章:

c++ - 不简单,从 char[8] 转换 long long

c:计算中使用的赋值

c - 为什么要为一个 POSIX 函数包含多个 header ?

c# - 使用 agility pack 解析 html

java - 用于从 C 生成数据绑定(bind)的开源解析器?

c++ - 临时绑定(bind)到引用参数的默认参数的生命周期是多少?

c++ - char* 到随机生成的数据

c++ - 我如何才能优先发布绘画事件?

c++ - 在 Mac OSX 上从 Python 脚本调用 C++ 函数

java - 将 IDL 枚举解析为 Java 枚举