如何将 C++ flex 与 C++ Bison 连接起来?

2024-05-03

我正在尝试将 C++ flex 与 C++ bison 连接起来,但我被难住了。 Bison 3.8.1 手册有一个带有 C Flex 的 C++ Bison 示例。 Flex 2.6.4 没有示例。我试图解决的问题是如何向 C++(或 C)Bison 提供指向 C++ Flex 对象的实例指针。我最好的想法是使用YY_DECL定义要使用的 Flex 扫描仪# define YY_DECL bison::symbol_type flx->yylex()并通过解析器调用序列将 flx 传递给 Bison,重新定义“解析”。这样对吗?还有更好的方法吗?


将 Flex 和 Bison 切换到 C++ 就像添加标志一样简单%option c++ https://ftp.gnu.org/old-gnu/Manuals/flex-2.5.4/html_chapter/flex_19.html#SEC19 and %language "c++" https://www.gnu.org/software/bison/manual/html_node/A-Simple-C_002b_002b-Example.html分别, 在这两种情况下,这都会导致生成的代码变成可重入 https://stackoverflow.com/questions/2441351/what-is-a-re-entrant-parser,正如您所注意到的,这会干扰这两者之间的互操作性。

默认情况下,在 C 语言中,Flex 和 Bison 都将其状态存储在全局变量中。 在 C++ 中,它们是面向对象的。 Flex 有一个类yyFlexLexer野牛有课yy::parser。 在这种语言中,这是一种更自然的方法,此外,它还允许您通过创建这些类的新对象来多次运行解析器。您甚至可以在多线程程序中同时运行多个解析器。

然而,有一个问题。虽然词法分析器和解析器现在都是 C++ 且可重入,但它们仍然假设其对应部分是默认的不可重入代码。 因此,他们试图访问不再存在的全局状态变量。 解决这个问题需要一些修补。



一个最小的例子

一个完整的示例,可以复制粘贴作为新程序的基础,将比仅仅解释更有用。

让我们从一个简单的示例开始,该示例仅展示如何使 C++ Flex 和 Bison 进行通信。 我们将编写一个简短的 Flex-Bison 程序,该程序需要格式输入Hello X!并打印回来Goodbye X!.

fooLexer.ll:

%{
    #include "FooLexer.hh"
    #include "fooParser.tab.hh"
    
    #undef  YY_DECL
    #define YY_DECL int FooLexer::yylex(std::string *const yylval)
%}

%option c++ noyywrap

%option yyclass="FooLexer"

%%

[[:space:]] ;
Hello { return yy::parser::token::HELLO; }
[[:alpha:]]+ { *yylval = std::string(yytext, yytext + yyleng); return yy::parser::token::WORLD; }
. { return yytext[0]; }

FooLexer.hh:

#pragma once

#include <string>
#if ! defined(yyFlexLexerOnce)
#include <FlexLexer.h>
#endif

class FooLexer : public yyFlexLexer
{
public:
    int yylex(std::string *const yylval);
};

这两个文件是我们的词法分析器。 我们不使用默认的词法分析器类,而是定义自己的继承自它的类。 我们这样做是因为默认实现不接受函数的参数yylex我们需要一个通过yylval进去。

让我们来分解一下最有趣的几行:

  • #undef YY_DECL- C++ Flex 仍然大量使用宏。YY_DECL https://ftp.gnu.org/old-gnu/Manuals/flex-2.5.4/html_chapter/flex_10.html#SEC10存储函数的声明yylval它将产生。 我们删除默认值,即int FooLexer::yylex().
  • #define YY_DECL int FooLexer::yylex(std::string *const lval)- 现在,我们用我们需要的函数声明替换删除的值。
  • %option c++ https://ftp.gnu.org/old-gnu/Manuals/flex-2.5.4/html_chapter/flex_19.html#SEC19- 我们将输出语言切换为 C++。
  • %option yyclass="FooLexer"- 最后,我们设置词法分析器应该使用哪个类而不是yyFlexLexer。 它将创建该方法yylex在这堂课上。
  • #include <FlexLexer.h>- 与 C 代码不同,Flex 生成的 C++ 代码需要外部标头FlexLexer.h https://ftp.gnu.org/old-gnu/Manuals/flex-2.5.4/html_chapter/flex_19.html#SEC19。 它应该与 Flex 一起安装在您的系统中。
  • #if ! defined(yyFlexLexerOnce) & #endif- 我们使用 Flex 机制来确保 header<lexLexer.h>仅添加一次。 (这是一个有点非标准的解决方案,但如果需要的话,我们可以多次包含它。)
  • int yylex(std::string *const yylval);- 我们确实声明了该函数,但定义是由 Flex 提供的。

fooParser.yy:

%require "3.2"
%language "c++"

%code requires {
    #include <string>
    #include "FooLexer.hh"
}

%define api.value.type {std::string}

%parse-param {FooLexer &lexer}

%header

%code {
    #define yylex lexer.yylex
}

%token HELLO
%token WORLD

%%

hello_world: HELLO WORLD '!' { std::cout << "Goodbye " << $WORLD << '!' << std::endl; }

%%

void yy::parser::error(const std::string &message)
{
    std::cerr << "Error: " << message << std::endl;
}

对于解析器,我们不创建自己的类。 Bison 在这方面更聪明一些,它使得调整代码变得更加简单。 例如,它正确地猜测应该采取yylval作为一个论据,所以我们不需要担心这一点。

尽管如此,还是有一些值得注意的变化:

  • %require "3.2" https://www.gnu.org/software/bison/manual/html_node/Require-Decl.html- 该指令不仅确保安装的 Bison 版本支持 C++。 它还可以防止创建冗余结果文件stack.hh.
  • %language "c++" https://www.gnu.org/software/bison/manual/html_node/A-Simple-C_002b_002b-Example.html- 我们将输出语言切换为 C++。
  • - 该指令向解析器类的构造函数添加了一个附加参数。 我们用它来将词法分析器传递给解析器。
  • #define yylex lexer.yylex- 解析器仍然假设yylex是一个全局函数。 我们使用预处理器将其更改为我们传递给构造函数的词法分析器的方法。
  • void yy::parser::error(const std::string &message)- 我们不再需要在文件开头声明错误处理程序。 然而,我们仍然需要定义它。该定义现在指向一个命名空间yy和班级parser这是解析器类的默认位置。

main.cc:

#include "FooLexer.hh"
#include "fooParser.tab.hh"

int main()
{
    FooLexer lexer;
    yy::parser parser(lexer);
    return parser();
}

现在我们只需要创建词法分析器和解析器类的对象就可以了。 解析器类是functor https://stackoverflow.com/questions/356950/what-are-c-functors-and-their-uses所以我们可以简单地调用它。


Bonus - makefile:

.RECIPEPREFIX = >

prog: main.o fooParser.tab.o lex.yy.o
> g++ $^ -o $@

main.o: main.cc FooLexer.hh fooParser.tab.hh
> g++ -c $< -o $@

lex.yy.o: lex.yy.cc FooLexer.hh fooParser.tab.hh
> g++ -c $< -o $@

fooParser.tab.o: fooParser.tab.cc FooLexer.hh
> g++ -c $< -o $@

lex.yy.cc: fooLexer.ll
> flex $<

fooParser.tab.hh fooParser.tab.cc fooParser.output: fooParser.yy
> bison $<

.PHONY: clean
clean:
> rm -f prog main.o lex.* fooParser.tab.* stack.hh


一个扩展的例子

让我们扩展这个示例,一方面了解如何添加/修改 C++ 解析器的各个方面,另一方面将其转换为可在实际应用程序中使用的代码。

目前,词法分析器和解析器位于不同的命名空间中,因此我们将它们放在同一个命名空间中(foo)。 我们还将把他们的名字改为我们选择的名字。 (这也包括原始词法分析器类的名称,出于稍后解释的技术原因。)

我们将修改词法分析器的构造函数,以便能够将文件传递给它,而不是读取标准输入。

我们将向解析器添加位置,以跟踪输入行号并给出更有意义的错误消息。

我们还将向程序添加打印调试日志的功能,以帮助编写复杂的解析器。

最后,我们将启用一些有用的杂项选项并添加一些辅助函数。


location_t.hh:

#pragma once

#include <cstddef>
#include <ostream>
#include <utility>

namespace foo
{
    using position_t = std::size_t;
    using location_t = std::pair<std::size_t, std::size_t>;
}

inline std::ostream& operator<<(std::ostream& os, const foo::location_t& loc)
{
    return os << "[" << loc.first << "-" << loc.second << "]";
}

为了在 Bison 中跟踪令牌位置,我们可以使用默认提供的位置类实现,也可以创建我们自己的位置类。 我发现默认实现有点缺乏,所以我们采用了第二个选项。

Bison 将与位置相关的类型命名如下:

  • “位置” - 文件中的特定点(默认 Bison 实现 https://www.gnu.org/software/bison/manual/html_node/C_002b_002b-position.html),
  • “location” - 由其开始和结束位置定义的令牌位置(默认 Bison 实现 https://www.gnu.org/software/bison/manual/html_node/C_002b_002b-location.html).

为了保持一致性,我们在实现中使用了相同的约定。

这是一个非常简单的实现,其中位置只是一个整数,存储行号。 在实际程序中,我建议至少跟踪行号和列,甚至可能跟踪文件中的绝对位置。

我们还添加了operator<<为我们的位置。 它通常很有用,但在我们的例子中,它是严格必需的,因为 Bison 在调试日志中使用它(我们将启用它)。


fooLexer.ll:

%{
    #include "FooLexer.hh"
    #include "fooParser.tab.hh"
    
    using namespace foo;
    
    #undef  YY_DECL
    #define YY_DECL int FooLexer::yylex(std::string *const lval, location_t *const lloc)
    
    #define YY_USER_INIT yylval = lval; yylloc = lloc;
    
    #define YY_USER_ACTION copyLocation();
%}

%option c++ noyywrap debug

%option yyclass="FooLexer"
%option prefix="yy_foo_"

%%

%{
    using Token = FooBisonParser::token;
%}

\n { ++currentLine; }
[[:space:]] ;
Hello { return Token::HELLO; }
[[:alpha:]]+ { copyValue(); return Token::WORLD; }
. { return yytext[0]; }

FooLexer.hh:

#pragma once

#include <string>
#if ! defined(yyFlexLexerOnce)
#define yyFlexLexer yy_foo_FlexLexer
#include <FlexLexer.h>
#undef yyFlexLexer
#endif
#include "location_t.hh"

namespace foo
{
    class FooLexer : public yy_foo_FlexLexer
    {
        std::size_t currentLine = 1;
        
        std::string *yylval = nullptr;
        location_t *yylloc = nullptr;
        
        void copyValue(const std::size_t leftTrim = 0, const std::size_t rightTrim = 0, const bool trimCr = false);
        void copyLocation() { *yylloc = location_t(currentLine, currentLine); }
        
    public:
        FooLexer(std::istream &in, const bool debug) : yy_foo_FlexLexer(&in) { yy_foo_FlexLexer::set_debug(debug); }
        
        int yylex(std::string *const lval, location_t *const lloc);
    };
    
    inline void FooLexer::copyValue(const std::size_t leftTrim, const std::size_t rightTrim, const bool trimCr)
    {
        std::size_t endPos = yyleng - rightTrim;
        if (trimCr && endPos != 0 && yytext[endPos - 1] == '\r')
            --endPos;
        *yylval = std::string(yytext + leftTrim, yytext + endPos);
    }
}

我们的词法分析器有很多变化,其中大部分启用了位置,少数是编辑命名空间和名称,其余的只是为了我们将来的方便:

  • using namespace foo;- 我们无法将词法分析器的整个代码放入命名空间中,因此这是下一个最佳选择。 (这被认为是一种不好的做法 https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice但我认为在这种特殊情况下它是无害的。)
  • #define YY_DECL int FooLexer::yylex(std::string *const lval, location_t *const lloc)- 我们添加了一个参数lloc到解析器,这是解析器传递的位置。 (YY_DECL https://ftp.gnu.org/old-gnu/Manuals/flex-2.5.4/html_chapter/flex_10.html#SEC10)
  • #define YY_USER_INIT yylval = lval; yylloc = lloc;- 我们无法编写自己的实现yylex but YY_USER_INIT https://ftp.gnu.org/old-gnu/Manuals/flex-2.5.4/html_chapter/flex_14.html#SEC14让我们在默认实现的开头插入一些额外的代码。 我们用它来将函数参数保存到对象的字段中。 这将使我们可以轻松地通过其他方法访问它们。
  • #define YY_USER_ACTION copyLocation(); - YY_USER_ACTION https://ftp.gnu.org/old-gnu/Manuals/flex-2.5.4/html_chapter/flex_14.html#SEC14插入到词法分析器中每个操作的前面。 我们用它来将每个令牌的位置复制到yylloc.
  • %option prefix="yy_foo_"- 我们更改了默认值prefix https://ftp.gnu.org/old-gnu/Manuals/flex-2.5.4/html_chapter/flex_17.html#SEC17 yyFlex 用于yy_foo_。 实际上,这会将内部词法分析器类(我们继承的类)的名称更改为yy_foo_FlexLexer。 如果我们的程序中需要多个词法分析器,那么这是必要的。 在这种情况下,每个词法分析器都需要不同的前缀以避免名称冲突。
  • using Token = FooBisonParser::token;- 这只是让我们写Token实际行动而不是完整行动FooBisonParser::token https://www.gnu.org/software/bison/manual/html_node/C_002b_002b-Parser-Interface.html#index-token-1.
  • \n { ++currentLine; }- 我们仍然不会在任何空白处发出标记,但每次遇到换行符时我们都需要增加内部行计数器。
  • #define yyFlexLexer yy_foo_FlexLexer & #undef yyFlexLexer- 并非所有词法分析器的代码都会生成。我们还包括了不知道我们已经更改了词法分析器前缀的头文件。 这trick https://ftp.gnu.org/old-gnu/Manuals/flex-2.5.4/html_chapter/flex_19.html#SEC19解决这个问题。 (如果您有多个词法分析器,则需要多次包含此标头,并使用不同的#defines.)
  • std::size_t currentLine = 1;- 我们的内部字段,我们用来跟踪当前行号yylloc.
  • std::string *yylval = nullptr; & location_t *yylloc = nullptr;- 带有解析器传递的指针副本的字段yylex。 它们在这里是为了更容易地在类的其他方法中访问这些指针。
  • void copyValue(const std::size_t leftTrim = 0, const std::size_t rightTrim = 0, const bool trimCr = false);- 一个方便的方法,让我们轻松复制当前内容yytext into yylval。 我们可以在行动中使用它。 我发现从字符串的开头和结尾截去一些字符的选项非常有用,例如当我们匹配一个字符串文字并且只想复制其内容而不需要复制它时"。 删除尾随的选项'\r'也有用途。
  • void copyLocation()- 将当前令牌的位置保存到的便捷方法yylloc。 如果语法中有多行标记,情况会变得更加复杂。
  • FooLexer(std::istream &in, const bool debug) : yy_foo_FlexLexer(&in) { yy_foo_FlexLexer::set_debug(debug); }- 我们向构造函数添加了更多参数,这让我们可以选择输入源,并在词法分析器中打开调试日志。

fooParser.yy:

%require "3.2"
%language "c++"

%code requires {
    #include <string>
    #include "location_t.hh"
    #include "FooLexer.hh"
}

%define api.namespace {foo}
%define api.parser.class {FooBisonParser}
%define api.value.type {std::string}
%define api.location.type {location_t}

%locations
%define parse.error detailed
%define parse.trace

%header
%verbose

%parse-param {FooLexer &lexer}
%parse-param {const bool debug}

%initial-action
{
    #if YYDEBUG != 0
        set_debug_level(debug);
    #endif
};

%code {
    namespace foo
    {
        template<typename RHS>
        void calcLocation(location_t &current, const RHS &rhs, const std::size_t n);
    }
    
    #define YYLLOC_DEFAULT(Cur, Rhs, N) calcLocation(Cur, Rhs, N)
    #define yylex lexer.yylex
}

%token HELLO
%token WORLD

%expect 0

%%

hello_world: HELLO WORLD '!' { std::cout << "Goodbye " << $WORLD << '!' << std::endl; }

%%

namespace foo
{
    template<typename RHS>
    inline void calcLocation(location_t &current, const RHS &rhs, const std::size_t n)
    {
        current = location_t(YYRHSLOC(rhs, 1).first, YYRHSLOC(rhs, n).second);
    }
    
    void FooBisonParser::error(const location_t &location, const std::string &message)
    {
        std::cerr << "Error at lines " << location << ": " << message << std::endl;
    }
}

当涉及到我们即将进行的更改时,Bison 界面比 Flex 更加用户友好,但添加自定义位置仍然需要大量代码。

  • %define api.namespace {foo} https://www.gnu.org/software/bison/manual/html_node/C_002b_002b-Bison-Interface.html- 我们已指示 Bison 将其所有代码放入命名空间中foo而不是默认的yy.
  • %define api.parser.class {FooBisonParser} https://www.gnu.org/software/bison/manual/html_node/_0025define-Summary.html#index-_0025define-api_002eparser_002eclass- 我们已经指示 Bison 命名它的解析器类FooBisonParser而不是默认的parser.
  • %define api.location.type {location_t} https://www.gnu.org/software/bison/manual/html_node/_0025define-Summary.html#index-_0025define-api_002elocation_002etype- 我们已指示 Bison 使用我们的位置类型而不是默认位置类型。 (see also https://www.gnu.org/software/bison/manual/html_node/User-Defined-Location-Type.html)
  • %locations https://www.gnu.org/software/bison/manual/html_node/Decl-Summary.html#index-_0025locations我们已指示 Bison 生成处理位置所需的代码。 这会导致一些方法的声明获得一个附加参数 - 位置。 (这包括yylex.) 我们还需要编写一个新函数来计算由多个较小令牌组成的令牌的位置。
  • %define parse.error detailed https://www.gnu.org/software/bison/manual/html_node/_0025define-Summary.html#index-_0025define-parse_002eerror- 我们已指示 Bison 生成更详细的错误消息,而不仅仅是“语法错误”。
  • %define parse.trace https://www.gnu.org/software/bison/manual/html_node/Enabling-Traces.html#index-_0025define-parse_002etrace-1- 我们已指示 Bison 生成可以在执行期间打印调试日志的代码。
  • %verbose https://www.gnu.org/software/bison/manual/html_node/Decl-Summary.html#index-_0025verbose- 我们已指示 Bison 生成额外的输出文件fooParser.output其中包含生成的状态机的人类可读的描述。 作为解释调试日志的参考非常有用。
  • %parse-param {const bool debug} https://www.gnu.org/software/bison/manual/html_node/Parser-Function.html#index-_0025parse_002dparam- 我们向解析器的构造函数添加了一个附加参数。
  • set_debug_level(debug); https://www.gnu.org/software/bison/manual/html_node/C_002b_002b-Parser-Interface.html#index-set_005fdebug_005flevel-on-parser- 我们使用 new 构造函数参数的值来决定是否打印调试日志。 (%initial-action https://www.gnu.org/software/bison/manual/html_node/Initial-Action-Decl.html#index-_0025initial_002daction-1)
  • #if YYDEBUG != 0 & #endif- 这是一个额外的故障保护,如果没有,则允许编译%define parse.trace https://www.gnu.org/software/bison/manual/html_node/Enabling-Traces.html#index-_0025define-parse_002etrace-1. (YYDEBUG https://www.gnu.org/software/bison/manual/html_node/Enabling-Traces.html#index-YYDEBUG)
  • void calcLocation(location_t &current, const RHS &rhs, const std::size_t n);- 该函数将获取较大令牌的所有子令牌的位置,并计算其位置。 在我们的例子中,我们只获取第一个标记的开始位置和最后一个标记的结束位置。
  • #define YYLLOC_DEFAULT(Cur, Rhs, N) calcLocation(Cur, Rhs, N) https://www.gnu.org/software/bison/manual/html_node/Location-Default-Action.html- 我们已指示 Bison 使用我们的函数来计算位置。
  • %expect 0 https://www.gnu.org/software/bison/manual/html_node/Expect-Decl.html- 此行确保语法中不存在冲突。 它对于跟踪我们已经知道和允许的冲突数量很有用。
  • void FooBisonParser::error(const location_t &location, const std::string &message)- 现在,打印错误消息的函数还需要获取错误的位置。

main.cc:

#include <cstring>
#include <iostream>
#include "FooLexer.hh"
#include "fooParser.tab.hh"

int main(int argc, char* argv[])
{
    const bool debug = argc > 1 && std::strcmp(argv[1], "--debug") == 0;
    foo::FooLexer lexer(std::cin, debug);
    foo::FooBisonParser parser(lexer, debug);
    return parser();
}

main 函数的主要变化是它检查程序是否使用标志调用--debug并将此信息传递给词法分析器和解析器。

我们还明确地通过std::cin https://en.cppreference.com/w/cpp/io/cin作为词法分析器的输入。 与前面的示例相比,这并没有改变任何内容,但我们可以轻松地将其更改为std::istream https://en.cppreference.com/w/cpp/io/basic_istream打开一个文件,甚至是程序中的一些内部流。


Bonus - makefile:

.RECIPEPREFIX = >

prog: main.o fooParser.tab.o lex.yy_foo_.o
> g++ $^ -o $@

main.o: main.cc FooLexer.hh fooParser.tab.hh location_t.hh
> g++ -c $< -o $@

lex.yy_foo_.o: lex.yy_foo_.cc FooLexer.hh fooParser.tab.hh location_t.hh
> g++ -c $< -o $@

fooParser.tab.o: fooParser.tab.cc FooLexer.hh location_t.hh
> g++ -c $< -o $@

lex.yy_foo_.cc: fooLexer.ll
> flex $<

fooParser.tab.hh fooParser.tab.cc fooParser.output: fooParser.yy
> bison $<

.PHONY: clean
clean:
> rm -f prog main.o lex.* fooParser.tab.* fooParser.output
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将 C++ flex 与 C++ Bison 连接起来? 的相关文章

  • 如何检查图像对象与资源中的图像对象是否相同?

    所以我试图创建一个简单的程序 只需在单击图片框中更改图片即可 我目前只使用两张图片 所以我的图片框单击事件函数的代码 看起来像这样 private void pictureBox1 Click object sender EventArgs
  • 如何验证文件名称在 Windows 中是否有效?

    是否有一个 Windows API 函数可以将字符串值传递给该函数 该函数将返回一个指示文件名是否有效的值 我需要验证文件名是否有效 并且我正在寻找一种简单的方法来完成此操作 而无需重新发明轮子 我正在直接使用 C 但针对的是 Win32
  • 无法使用已与其底层 RCW 分离的 COM 对象。在 oledb 中

    我收到此错误 但我不知道我做错了什么 下面的代码在backrgroundworker中 将异常详细信息复制到剪贴板 System Runtime InteropServices InvalidComObjectException 未处理 通
  • C# 和 Javascript SHA256 哈希的代码示例

    我有一个在服务器端运行的 C 算法 它对 Base64 编码的字符串进行哈希处理 byte salt Convert FromBase64String serverSalt Step 1 SHA256Managed sha256 new S
  • ASP.NET Core Serilog 未将属性推送到其自定义列

    我有这个设置appsettings json对于我的 Serilog 安装 Serilog MinimumLevel Information Enrich LogUserName Override Microsoft Critical Wr
  • 如何在列表框项目之间画一条线

    我希望能够用水平线分隔列表框中的每个项目 这只是我用于绘制项目的一些代码 private void symptomsList DrawItem object sender System Windows Forms DrawItemEvent
  • 如何忽略“有符号和无符号整数表达式之间的比较”?

    谁能告诉我必须使用哪个标志才能使 gcc 忽略 有符号和无符号整数表达式之间的比较 警告消息 gcc Wno sign compare 但你确实应该修复它警告你的比较
  • 实时服务器上的 woff 字体 MIME 类型错误

    我有一个 asp net MVC 4 网站 我在其中使用 woff 字体 在 VS IIS 上运行时一切正常 然而 当我将 pate 上传到 1and1 托管 实时服务器 时 我得到以下信息 网络错误 404 未找到 http www co
  • Newtonsoft JSON PreserveReferences处理自定义等于用法

    我目前在使用 Newtonsoft Json 时遇到一些问题 我想要的很简单 将要序列化的对象与所有属性和子属性进行比较以确保相等 我现在尝试创建自己的 EqualityComparer 但它仅与父对象的属性进行比较 另外 我尝试编写自己的
  • 如何将图像和 POST 数据上传到 Azure 移动服务 ApiController 终结点?

    我正在尝试上传图片and POST表单数据 尽管理想情况下我希望它是json 到我的端点Azure 移动服务应用 我有ApiController method HttpPost Route api upload databaseId sea
  • 将目录压缩为单个文件的方法有哪些

    不知道怎么问 所以我会解释一下情况 我需要存储一些压缩文件 最初的想法是创建一个文件夹并存储所需数量的压缩文件 并创建一个文件来保存有关每个压缩文件的数据 但是 我不被允许创建许多文件 只能有一个 我决定创建一个压缩文件 其中包含有关进一步
  • Discord.net 无法在 Linux 上运行

    我正在尝试让在 Linux VPS 上运行的 Discord net 中编码的不和谐机器人 我通过单声道运行 但我不断收到此错误 Unhandled Exception System Exception Connection lost at
  • 将 xml 反序列化为类,list<> 出现问题

    我有以下 XML
  • C++ 复制初始化和直接初始化,奇怪的情况

    在继续阅读本文之前 请阅读在 C 中 复制初始化和直接初始化之间有区别吗 https stackoverflow com questions 1051379 is there a difference in c between copy i
  • C++ fmt 库,仅使用格式说明符格式化单个参数

    使用 C fmt 库 并给定一个裸格式说明符 有没有办法使用它来格式化单个参数 example std string str magic format 2f 1 23 current method template
  • 需要哪个版本的 Visual C++ 运行时库?

    microsoft 的最新 vcredist 2010 版 是否包含以前的版本 2008 SP1 和 2005 SP1 还是我需要安装全部 3 个版本 谢谢 你需要所有这些
  • C 中的异或运算符

    在进行按位操作时 我在确定何时使用 XOR 运算符时遇到一些困难 按位与和或非常简单 当您想要屏蔽位时 请使用按位 AND 常见用例是 IP 寻址和子网掩码 当您想要打开位时 请使用包含或 然而 XOR 总是让我明白 我觉得如果在面试中被问
  • 限制C#中的并行线程数

    我正在编写一个 C 程序来生成并通过 FTP 上传 50 万个文件 我想并行处理4个文件 因为机器有4个核心 文件生成需要更长的时间 是否可以将以下 Powershell 示例转换为 C 或者是否有更好的框架 例如 C 中的 Actor 框
  • 使用按位运算符相乘

    我想知道如何使用按位运算符将一系列二进制位相乘 但是 我有兴趣这样做来查找二进制值的十进制小数值 这是我正在尝试做的一个例子 假设 1010010 我想使用每个单独的位 以便将其计算为 1 2 1 0 2 2 1 2 3 0 2 4 虽然我
  • 恢复上传文件控制

    我确实阅读了以下帖子 C 暂停 恢复上传 https stackoverflow com questions 1048330 pause resume upload in c 使用 HTTP 恢复上传 https stackoverflow

随机推荐

  • TSQL 多列唯一约束也允许多个 Null

    我目前正在做一些从 MS Access 到 SQL Server 的迁移 Access 允许唯一索引中存在多个 Null 而 SQL Server 不允许 我一直在通过删除 SQL Server 中的索引并添加筛选索引来处理迁移 CREAT
  • 启动jetty服务器时出现NoClassDefFoundError

    我正在尝试在码头服务器中托管我的网络应用程序 spring 我将 war 文件复制到 jetty 服务器中的 webapp 文件夹中 我并不是想嵌入jetty服务器 而是试图在jetty内托管应用程序 如tomcat 我没有安装jetty
  • 如何在 Microsoft Visual Studio 2017 中检查 C++ 版本

    我正在尝试使用以下代码检查我拥有的 C 版本 if cplusplus 201703L std cout lt lt C 17 n else if cplusplus 201402L std cout lt lt C 14 n else i
  • 如何减少 MediaCodec H264 编码器延迟

    我正在尝试使用 Android6 0 的 MediaCodec 将 h264 实时低延迟编码为流 编码器大约有 6 帧延迟 我想知道如何减少 代码来自屏幕记录 cpp https android googlesource com platf
  • 使用 Flask-restful RequestParser 进行嵌套验证

    使用烧瓶宁静 http flask restful readthedocs org 微框架 我在构建一个RequestParser这将验证嵌套资源 假设预期的 JSON 资源格式为 a list obj1 1 obj2 2 obj3 3 o
  • ios ScheduledTimerWithTimeInterval 的时间量

    我想使用 ScheduledTimerWithTimeInterval 来执行一定时间的定期任务 比如说一小时 但我如何在我的代码上实现 这是我的代码 timer NSTimer scheduledTimerWithTimeInterval
  • TFS自定义签入策略调试

    我创建了一个自定义签入政策 如下面的链接所示 http msdn microsoft com en us library bb668980 aspx http msdn microsoft com en us library bb66898
  • 范围对象 - 为什么有时我不能使用工作表

    在这个线程中 Excel VBA 查找特定工作表上范围内的最大值 https stackoverflow com questions 31906571 excel vba find maximum value in range on spe
  • 如何在 Rollup 中配置从多个输入文件仅生成单个输出文件?

    配置Rollupjs生成库时 如果输入是由多个javascript文件组成的数组 我们如何才能将这些输入生成为一个输出 js 文件呢 export const lgService input src app services livegiv
  • 如何在IE8及以下浏览器中应用边框半径?

    我想知道如何将 border radius 应用于 IE8 及以下 IE8 浏览器 我知道 border radius 是 HTML5 的一项功能 而 IE8 不支持它 我发现通过使用 htc 我们可以实现这一点 但是通过使用 htc 我遇
  • Node.js npm mssql 函数返回未定义

    我使用 mssql 和 node js 连接到 sql server 数据库 我试图通过将连接代码包装在具有一个查询参数的函数中来减少代码 当我从 router get 函数中的 with 调用该函数时 它返回未定义 任何帮助将非常感激 f
  • WPF - 非常基本的 ListBox.ItemTemplate 问题

    好吧 这是一个看似简单得令人尴尬的问题 但却让我发疯 我正在学习 DataTemplate 并尝试将一个非常非常简单的 ItemTemplate 应用于 ListBox 然而 当我运行我的应用程序时 模板被完全忽略 我只得到标准外观的列表框
  • 获取SSAS立方体上次处理时间

    在 Excel 中 我与数据多维数据集建立 Analysis Services 连接 我希望能够通过向用户显示最后一次多维数据集处理时间发生的时间来向用户展示数据的最新情况 在 SQL Server Management Studio SS
  • 使用 System.loadLibrary() 时出现不满意的链接错误?

    由于某种原因 我在我的 java 应用程序中遇到了令人讨厌的不满意链接错误 这是所涉犯罪者 System loadLibrary psjw 尽管库 psjw dll 显然与此类位于同一源包中 请帮忙 确保 psjw dll 位于您的 PAT
  • 事件溯源:在重放事件并监听新传入事件时避免项目重复事件

    在需要构建新视图的场景中 我们可以重播来自活动商店 结果 我们将投影出新的视图 因此 我们的想法是部署一个新的投影 该投影可以投影所有旧事件 通过重播 并监听新传入的事件并投影它们 我认为在读取旧事件和收听新传入事件时可能会发生比赛条件 因
  • 如何在android中的google(设备)本机应用程序上添加自定义按钮?

    我想在谷歌 设备 的本机应用程序上添加一个按钮 例如 谷歌地图 使用此按钮我想打开我的应用程序 我已经做了一些相关工作 Using 无障碍服务 https developer android com reference android ac
  • 如何以 HDF5 格式提供 caffe 多标签数据?

    我想将 caffe 与矢量标签一起使用 而不是整数 我检查了一些答案 似乎 HDF5 是更好的方法 但后来我陷入了这样的错误 precision layer cpp 34 检查失败 outer num inner num bottom 1
  • 如何获取 Windows Phone 的设备令牌 ID 以进行推送通知?

    我正在使用 Visual Studio 2012 在手机间隙 移动 jquery 中创建 Windows Phone 8 应用程序 我想从设备获取设备令牌 id 以用于推送通知 谁能指导我如何获取 Windows Phone 8 的设备令牌
  • LINQ to SQL 选择“按多列区分”并返回整个实体

    我正在使用第三方数据库 需要为我正在研究的特定市场选择一组不同的数据 每个市场的数据都是相同的 因此将其全部引入是多余的 并且我不想硬编码围绕它的任何逻辑 因为我们正在与供应商合作解决问题 但我们需要一个修复程序与供应商合作修复以及数据库当
  • 如何将 C++ flex 与 C++ Bison 连接起来?

    我正在尝试将 C flex 与 C bison 连接起来 但我被难住了 Bison 3 8 1 手册有一个带有 C Flex 的 C Bison 示例 Flex 2 6 4 没有示例 我试图解决的问题是如何向 C 或 C Bison 提供指