标签: ragel

ANTLR是否是用于序列化/反序列化二进制数据格式的适当工具?

我需要读写八位字节流,通过各种网络发送,与智能电表进行通信.ANSI标准ANSI C12.19描述了二进制数据格式.虽然数据格式不是太复杂,但标准非常大(500多页),因为它描述了许多不同的类型.该标准由EBNF语法完整描述.我正在考虑利用ANTLR来读取EBNF语法或它的修改版本,并创建可以读写八位字节流的C#类.

这是一个很好的使用ANTLR?

如果是这样,我需要做些什么才能使用ANTLR 3.1?从搜索新闻组档案看来,我似乎需要实现一个可以读取字节而不是字符的新流.是全部还是我必须实现Lexer衍生物?

如果ANTLR可以帮助我读取/解析流,它还可以帮助我编写流吗?

谢谢.

丹芬卡

parsing antlr generator ebnf ragel

10
推荐指数
2
解决办法
3015
查看次数

Parser Generators和Ragel ......制作我自己的D Parser

我是编译器世界的新手,我最近听说过一种称为解析器生成器的东西.从我(我认为)我所理解的,解析器生成器接收语法文件并输出可以使用给定语法解析文件的源代码文件.

几个问题:

  1. 我理解正确吗?

  2. 如果是这样,Ragel是这样的工具吗?

  3. 如果是,Ragel可以将D解析器输出为D源代码吗?

谢谢!

d parser-generator ragel

10
推荐指数
2
解决办法
2571
查看次数

如何在Ragel中解析模板语言?

我一直在研究简单模板语言的解析器.我正在使用Ragel.

要求是适度的.我正在尝试找到可以嵌入输入字符串中任何位置的[[tags]].

我正在尝试解析一个简单的模板语言,可以在HTML中嵌入{{foo}}等标记.我尝试了几种方法来解析这个问题,但不得不求助于使用Ragel扫描程序并使用低效的方法,只将单个字符匹配为"全部捕获".我觉得这是错误的做法.我基本上滥用扫描仪的最长匹配偏差来实现我的默认规则(它只能是1个字符长,所以它应该永远是最后的手段).

%%{

  machine parser;

  action start      { tokstart = p; }          
  action on_tag     { results << [:tag, data[tokstart..p]] }            
  action on_static  { results << [:static, data[p..p]] }            

  tag  = ('[[' lower+ ']]') >start @on_tag;

  main := |*
    tag;
    any      => on_static;
  *|;

}%%
Run Code Online (Sandbox Code Playgroud)

(用红宝石写的动作,但应该很容易理解).

How would you go about writing a parser for such a simple language? Is Ragel maybe not the right tool? It seems you have to fight Ragel tooth and nails if the syntax is …

parsing fsm lexer ragel

9
推荐指数
1
解决办法
2419
查看次数

哪个面向Java的lexer解析器用于简单项目(ANTLR,DIY等)

我正在研究一个小型文本编辑器项目,并希望为几种语言添加基本的语法高亮(Java,XML ......仅举几例).作为一种学习经历,我想添加一个流行或非流行的Java词法分析器.

你推荐什么项目.Antlr可能是最知名的,但它似乎相当复杂和沉重.

这是我所知道的选项.

  1. ANTLR
  2. Ragel(是的,它可以生成用于处理输入的Java源代码)
  3. 自己动手(我想我可以编写一个简单的令牌解析器并突出显示源代码).

java dsl parsing antlr ragel

7
推荐指数
1
解决办法
6483
查看次数

简单的Ragel示例平衡括号?

这是语法的起点:

%%{
  machine xo;

  char = "x" | "o";
  group = "(" char* ")";
  main := group;
}%%
Run Code Online (Sandbox Code Playgroud)

(xxxx(oo)()xx)例如,它处理.如何扩展它以允许嵌套组; 例如(xxxx(o(x)o)()xx

我知道递归通常不是由一台Ragel机器支持的.所以这不起作用:

group = "(" ( char | group )* ")";
Run Code Online (Sandbox Code Playgroud)

来自Ragel状态机编译器用户指南(PDF) :(为了强调而添加了粗体文本):

"一般来说,Ragel无法处理递归结构,因为语法被解释为常规语言.但是,根据需要解析的内容,使用手动编码技术实现递归部分有时是实用的.这通常适用于递归结构的情况简单易懂,比如平衡括号."

"解析递归结构的一种方法是使用递增和递减计数器的操作,或以其他方式识别递归结构的入口和退出结构,然后使用fcall和fret跳转到适当的机器定义.或者,语义条件可用于测试计数器变量.

"更传统的方法是在输入递归结构时调用单独的解析函数(以主机语言表示),然后在识别结束时返回."

嵌套括号的邮件列表讨论中,提到了相同的三种方法:

  1. 使用prepush和postpop指定可增长的堆栈,然后使用fcall和fret.

  2. 计算然后在操作或条件中进行验证.

  3. 输入递归结构时,调用新的解析函数(使用宿主语言).

你能指点我的一个例子 - 最好是用我上面的例子 - 在Ruby中吗?谢谢!

ruby ragel

7
推荐指数
1
解决办法
2105
查看次数

如何让Ragel EOF动作起作用

我正在与Ragel一起评估FSA,我想嵌入一个用户操作,只要我的机器完成测试输入就会运行.无论机器是否以接受状态结束,我都需要执行此操作.我从Ragel指南中获取了这个修改过的示例,说明了我的目标:

#include <string.h>
#include <stdio.h>

%%{
    machine foo;
    main := ( 'foo' | 'bar' ) 0 @{ res = 1; } $/{ finished = 1; };
}%%
%% write data;
int main( int argc, char **argv ) {
    int cs, res = 0, finished = 0;
    if ( argc > 1 ) {
        char *p = argv[1];
        char *pe = p + strlen(p) + 1;
        char* eof = pe;
        %% write init;
        %% write exec;
    }

    printf("result = %i\n", res …
Run Code Online (Sandbox Code Playgroud)

c finite-automata state-machine ragel

6
推荐指数
1
解决办法
1023
查看次数

如何使用Ragel正确扫描标识符

我正在尝试为我的C/C++/C#/ Java/D类编程语言编写一个扫描程序,这是我出于个人原因设计的.为此,我正在使用Ragel生成扫描仪.我很难理解许多操作员何时触发行动,可能是因为我的学者专注于实践知识而不是理论,而且大量的这种非确定性/确定性有限自动机业务正好在我脑海中.我发现文档要么缺乏,要么我对它的理解是如此.我假设后者.

无论如何,我正在从基础开始.我在第一次迭代中发现了几个关键字和特殊字符.现在我遇到了所有关键字都被扫描为标识符的问题.我正在使用扫描仪操作符来处理我的所有关键字,因为这解决了我的字符串returns被扫描为returnreturns关键字的问题.

如何正确扫描标识符?我理解为了使这个确定性,我需要有效地指定lexeme只能是一个identifier如果它不匹配其他令牌的模式.原谅我缺乏知识.

Ragel脚本:

%%{
    Identifier = (alpha | '_') . (alnum | '_')*;
    action IdentifierAction
    {
        std::cout << "identifier(\"";
        std::cout.write(ts, te - ts);
        std::cout << "\")";
    }
}%%

%%{
    main :=
    |*
        Interface => InterfaceAction;
        Class => ClassAction;
        Property => PropertyAction;
        Function => FunctionAction;
        TypeQualifier => TypeQualifierAction;
        OpenParenthesis => OpenParenthesisAction;
        CloseParenthesis => CloseParenthesisAction;
        OpenBracket => OpenBracketAction;
        CloseBracket => CloseBracketAction;
        OpenBrace => OpenBraceAction;
        CloseBrace => CloseBraceAction;
        Semicolon => SemicolonAction;
        Returns => …
Run Code Online (Sandbox Code Playgroud)

lexical-analysis ragel

4
推荐指数
1
解决办法
1277
查看次数

Ragel - 在输入时验证字符串

假设我们想要在用户输入JTextField时验证用户输入.为了验证用户输入,我想知道我是否可以使用Ragel.

假设输入应该遵循此示例正则表达式:

[a-z]{2,5}ABC[0-9]+
Run Code Online (Sandbox Code Playgroud)

我如何用ragel做到这一点?任何人都可以举一个简短的例子,说明如何使用ragel"动态"验证用户输入(输入时)?

Ragel文档错过了快速入门的一些好例子,所以我在这里问.

java validation input ragel

2
推荐指数
1
解决办法
1926
查看次数

如何让Ragel解析由(space*":"space*)分隔的两个名字?

我想解析以下内容:

name:name
Run Code Online (Sandbox Code Playgroud)

名称以alnum开头和结尾,并且可以包含alnum和space内部的任意组合.它们也可能是空白的.我的规则是:

identifier = alnum (space* alnum)*;
name       = (identifier | zlen) >sName $pName %fName;
Run Code Online (Sandbox Code Playgroud)

名称可以用冒号分隔,也可以选择名称和冒号之间的空格.我的规则是:

sep = space* ":" space*;
main := name sep name;
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为显然是space*identifierspace*sep混淆解析器.我最终fName在名称的每个空间中执行了操作.

如果我将sep更改为:

sep = ":";
Run Code Online (Sandbox Code Playgroud)

一切都很好.如何修改这些规则以使解析器完成我想要的操作?

这个问题的源代码:https://gist.github.com/1661150

c parsing lexical-analysis parser-generator ragel

2
推荐指数
1
解决办法
887
查看次数

匹配文件的开头或换行符(Ragel)

我用ragel和C作为主语.

我只能使用'\n'来识别换行符,但我需要识别文件的开头作为替代.

在正则表达式的其他实现中,这可以由\A或给出$,但是$为了其他目的而保留,'\A'映射到其他东西(警报?)并\A给出解析器错误.

ragel

2
推荐指数
1
解决办法
389
查看次数

用于C的有限状态机编译器来模拟网络协议

我正在寻找一个好的状态机编译器,以便测试一些自定义网络协议.我查看了一些工具,如Yakindu,Ragel(编译器),SCXML(语言),但我不确定是否有任何工具可用于网络协议.

SCXML(语言)看起来不错,但我找不到任何专门用于C的编译器(scxmlcc用于C++).有没有人知道基于SCXML的C编译器?Yakindu工具看起来很有前景,但我不确定是否可以测试像BGP/OSPF这样的网络协议.任何人都可以对此提出任何指示吗?Ragel看起来也不错,但我不确定是否可以使用此编译器生成复杂的网络协议客户端.

我特别提到网络协议的原因是我还希望能够在"事件"发生后执行自定义例程,例如packet_create/packet_send(具有自定义数据包大小)等,作为"操作"的一部分.

我是否需要始终从状态图生成代码,或者有没有办法直接与状态交互?我是FSM的新手,任何帮助/建议/建议/链接将不胜感激.

c network-protocols fsm ragel scxml

2
推荐指数
1
解决办法
904
查看次数

指针C和C++之间的区别

我注意到以下C代码给出了"警告:初始化从指针目标类型中丢弃限定符",但它仍然按预期编译和运行(输出'W'字符).

#include <stdio.h>
int main(int argc, char *argv[])
{
    char buffer[20] = {'H','e','l','l','o',' ','W','o','r','l','d','!','\0'};

    const char* p = &buffer[0];

    char* c = (p + 6);

    printf("%c\n",*c);
}
Run Code Online (Sandbox Code Playgroud)

在C++中,相当类似的代码根本不会编译抱怨"错误:从'const char*'到'char*'的无效转换"

#include <iostream>
using namespace std;
int main()
{
   char buffer[20] = {'H','e','l','l','o',' ','W','o','r','l','d','!','\0'};

   const char* p = &buffer[0];

   char* c = p + 6;

   cout << *c;
   cout << endl;
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

是什么原因?

是否有可能修复C++代码以使其编译(和行为)就像它的C对应物一样?

更好的解释:感谢您的所有答案,但大多数人没有得到我真正的问题所以我会尝试更详细地解释.

我正在使用用C编写的库.标题中的函数原型是这样的:

void parse (const char* p, uint16_t len, uint8_t is_eof);
Run Code Online (Sandbox Code Playgroud)

在这个函数的实现中,碰巧运行代码就好了

char* c = p …
Run Code Online (Sandbox Code Playgroud)

c c++ pointers arduino ragel

1
推荐指数
2
解决办法
3784
查看次数

在 C++ 代码库中使用 Ragel 解析字符串的原因是什么?

我继承了一个使用 Ragel 进行字符串解析的 C++ 项目。

这是我第一次看到这样做,我想了解为什么有人会使用 Ragel 而不是 C++ 来解析字符串?

c++ ragel

0
推荐指数
1
解决办法
888
查看次数