Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C的关键字标签值样式配置文件解析库_C_Parsing_Configuration Files - Fatal编程技术网

C的关键字标签值样式配置文件解析库

C的关键字标签值样式配置文件解析库,c,parsing,configuration-files,C,Parsing,Configuration Files,是否已经存在将读取以下样式文件的配置解析库: 关键字标签值 通过{}替换值进行嵌套;可选标签;支持“Include”就好了 示例配置文件可能如下所示: Listen Inside 127.0.0.1:1000; Listen Outside { IP 1.2.3.4; Port 1000; TLS { CertFile /path/to/file; }; }; ACL default_acl { IP 192.168.0.0/24;

是否已经存在将读取以下样式文件的配置解析库:

关键字标签值

通过
{}
替换值进行嵌套;可选标签;支持“Include”就好了

示例配置文件可能如下所示:

Listen Inside 127.0.0.1:1000;
Listen Outside {
    IP 1.2.3.4;
    Port 1000;
    TLS {
        CertFile /path/to/file;
    };
};
ACL default_acl {
    IP 192.168.0.0/24;
    IP 10.0.0.0/24;
};
存在C库的到和。它们看起来就像您所需要的。

存在C库的to和。它们看起来像你需要的东西。

你看过(或者是flex和bison)吗?这有点毛茸茸的,但我们使用它们来解析与您的配置文件完全相同的文件。您可以使用括号定义子结构,解析具有相同键的可变长度列表,等等

你所说的标签是指评论吗?您可以定义自己的注释结构,我们使用“#”表示注释行

它不支持包含AFAIK。

您看过(或者flex和bison)吗?这有点毛茸茸的,但我们使用它们来解析与您的配置文件完全相同的文件。您可以使用括号定义子结构,解析具有相同键的可变长度列表,等等

你所说的标签是指评论吗?您可以定义自己的注释结构,我们使用“#”表示注释行


它不支持包含AFAIK。

您熟悉哪些编程语言?你的问题给我的印象是C

您的配置语言的标记似乎是正则表达式:

  • 127.0.0.1:1000
  • 一千
  • )
  • {
  • }
  • 等等
几乎所有现代编程语言都有某种形式的支持

如果实现是C,我可能会使用flex。它生成一个函数,该函数将应用一组正则表达式,将匹配的文本放入一个C字符串中,并返回该正则表达式的类型(只返回一个int,由您选择)。该函数是“词法分析器”或“标记器”。它将字符流分割成符合您需要的方便单位,一次一个正则表达式

Flex非常容易使用。它比lex有几个优点。一个是可以有多个词法分析器函数,因此如果需要对include文件执行一些奇怪的操作,那么可以为该任务使用第二个词法分析器函数

你的语言看起来很简单。野牛/Yacc是非常强大的工具,“强大的力量带来巨大的责任”:-)

我认为它足够简单,我可以手工编写解析器。它可能只有几个函数来处理它的结构。一种非常简单的技术称为递归下降解析器。你有CS学位,或者了解这些东西吗

很多人(在这个阶段)会告诉你去买''或它的一个新版本,通常是因为他们在大学里就是这样的。龙之书很棒,但它就像告诉某人阅读所有维基百科来了解鲸鱼。如果你有时间,你会学到很多

这篇文章是一个合理的开始。递归下降法非常流行,因为它相对容易理解。使它变得简单的事情是有一个适当的语法,它被转换成一种易于递归下降解析的形式。然后,您可以为每个规则编写一个函数,并使用一个简单的错误处理机制(这就是为什么我问这个问题)。可能有工具可以生成它们,但您可能会发现编写它们会更快。第一次割伤可能需要一天的时间,然后你就可以做出决定了

一个非常漂亮的lex/flex特性是,任何不匹配的字符都只是回显到标准输出。因此,您可以查看正则表达式匹配的内容,并可以增量添加它们。当输出“干涸”时,所有内容都被匹配

Pontification alert:IMHO,更多的C程序员应该学会使用flex。它相对容易使用,并且对于文本处理非常强大。IMHO很多人都被推迟了,因为他们还被告知使用yacc/bison,这是一种更强大、更微妙、更复杂的工具。 结束自大

如果你需要一些语法方面的帮助,请询问。如果有一个很好的语法(可能不是这样,但到目前为止,您的示例看起来还不错),那么实现是简单的

我发现了两个指向stackoverflow答案的链接,看起来很有用:

下面是一个使用flex的示例

Flex接受一个“脚本”,并生成一个名为yylex()的C函数。这是输入脚本

请记住,所有正则表达式都在该yylex函数中匹配,因此尽管脚本看起来很奇怪,但它实际上是一个普通的C函数。为了告诉调用方(将是递归下降解析器)匹配的正则表达式类型,它返回一个您选择的整数值,就像任何普通C函数一样

如果没有什么可以告诉解析器的,比如空格,或者某种形式的注释,它就不会返回。它“无声地”消耗这些字符。如果语法需要使用换行符,那么它将被识别为一个标记,并向解析器返回一个合适的标记值。有时更容易让它更自由,因此本例会消耗并忽略所有空白

实际上,yylex函数是从第一个
%%
到第二个
%%
的所有函数。它的行为类似于一个大的
switch()
语句。
正则表达式类似于(非常奇特的)
大小写:
标签。
{…}
中的代码是普通C。它可以包含任何C语句,并且必须正确嵌套在
{…}

第一个
%%
之前的内容是放置flex定义的地方,以及一些flex的“说明”。
%{…%}
中的内容是普通C,可以
/* scanner for a configuration files */ 
%{ 
    /* Put headers in here */ 
#include <config.h>

%} 
%%
[0-9]+                  { return TOK_NUMBER; } 
[0-9]+"."[0-9]+"."[0-9]+"."[0-9]+":"[0-9]+ { return TOK_IP_PORT; } 
[0-9]+"."[0-9]+"."[0-9]+"."[0-9]+"/"[0-9]+ { return TOK_IP_RANGE; } 
"Listen"                { return TOK_KEYWORD_LISTEN; } 
[A-Za-z][A-Za-z0-9_]*   { return TOK_IDENTIFIER; }
"{"                     { return TOK_OPEN_BRACE; }
"}"                     { return TOK_CLOSE_BRACE; }
";"                     { return TOK_SEMICOLON; }
[ \t\n]+        /* eat up whitespace, do nothing */ 
.           { fprintf(stderr,  "Unrecognized character: %s\n", yytext ); 
              exit(1); 
            }
%%

/* -------- A simple test ----------- */
int main(int argc, char *argv[])
{ 
    int tok;
    yyin = stdin;
    while (tok=yylex()) {
        fprintf(stderr, "%d %s\n", tok, yytext);
    }
}
flex config.l
gcc lex.yy.c -ll
./a.out <tinytest
#ifndef _CONFIG_H_
#define _CONFIG_H_

enum TOKENS { 
 TOK_KEYWORD_LISTEN = 256, 
 TOK_IDENTIFIER = 257, 
 TOK_OPEN_BRACE = 258, 
 TOK_CLOSE_BRACE = 259, 
 TOK_SEMICOLON = 260, 
 TOK_IP_PORT = 261, 
 TOK_IP_RANGE = 262, 
 TOK_NUMBER = 263, 
};
#endif _CONFIG_H_