这是可以使用我们的多个免费在线工作站之一在 OnWorks 免费托管服务提供商中运行的命令 ragel,例如 Ubuntu Online、Fedora Online、Windows 在线模拟器或 MAC OS 在线模拟器
程序:
您的姓名
ragel - 将常规语言编译成可执行的状态机
概要
拉格尔 [选项] 文件
商品描述
Ragel 从常规语言编译可执行的有限状态机。 雷格罐头
生成 C、C++、Objective-C、D、Go 或 Java 代码。 Ragel 状态机不仅可以
像正则表达式机器一样识别字节序列,但也可以在以下位置执行代码
识别常规语言中的任意点。 用户代码嵌入使用
不会破坏常规语言语法的内联运算符。
核心语言由标准的正则表达式运算符组成,例如联合、
concatenation 和 kleene star,伴随着动作嵌入操作符。 雷格也
提供可让您控制您创建、构造的任何非确定性的运算符
扫描仪使用最长匹配范式,并使用状态图构建状态机
模型。 也可以从内部影响状态机的执行
通过跳转或调用机器的其他部分并重新处理来嵌入动作
输入。
Ragel 为试图放置的宿主语言提供了一个非常灵活的接口
对生成代码的使用和集成方式的最小限制
应用。 生成的代码没有依赖关系。
配置
-h, -H, -?, - 帮帮我
显示帮助并退出。
-v 打印版本信息并退出。
-o 文件
将输出写入文件。 如果未给出 -o,则选择默认文件名
替换输入文件的文件扩展名。 对于以 .rh 结尾的源文件
使用后缀 .h。 对于所有其他源文件,基于输出语言的后缀
使用(.c、.cpp、.m 等)。 如果未为 Graphviz 输出提供 -o,则生成的
dot 文件被写入标准输出。
-s 打印一些关于标准错误的统计信息。
--错误格式=gnu
使用格式“文件:行:列:”(默认)打印错误消息
--错误格式=msvc
使用格式“文件(行,列):”打印错误消息
-d 不要从操作列表中删除重复的操作。
-I DIR
将 dir 添加到目录列表以搜索包含和导入的文件
-n 不执行状态最小化。
-m 在状态机编译结束时执行一次最小化。
-l 几乎在每次操作后最小化。 类似操作(例如联合)的列表是
最后最小化一次。 这是默认的最小化选项。
-e 每次操作后最小化。
-x 编译状态机并发出主机数据的 XML 表示和
机器。
-V 为 Graphviz 生成一个点文件。
-p 在标签上显示可打印字符。
-S
FSM 规范输出。
-M
机器定义/实例化输出。
-C 宿主语言是 C、C++、Obj-C 或 Obj-C++。 这是默认的宿主语言
选项。
-D 宿主语言是 D。
-J 宿主语言是 Java。
-Z 宿主语言是 Go。
-R 宿主语言是 Ruby。
-L 禁止编写#line 指令。
-T0 (C/D/Java/Ruby/C#/Go) 生成一个表驱动的 FSM。 这是默认的代码样式。
表驱动的 FSM 将状态机表示为静态数据。 有桌子
状态、转换、索引和动作。 当前状态存储在
多变的。 执行是一个循环,看起来给定当前状态和
当前要处理的字符使用二分查找查找转换,
执行任何动作并移动到目标状态。 一般来说,表驱动
FSM 生成更小的二进制文件并且需要更便宜的宿主语言编译
但会导致代码运行速度变慢。 表驱动 FSM 适用于任何 FSM。
-T1 (C/D/Ruby/C#/Go) 通过扩展动作列表生成更快的表驱动 FSM
动作执行代码。
F0 (C/D/Ruby/C#/Go) 生成一个平面表驱动的 FSM。 转换表示为
由当前字母字符索引的数组。 这消除了对一个
二进制搜索来定位转换并生成更快的代码,但是它只是
适合小字母。
F1 (C/D/Ruby/C#/Go) 通过扩展动作列表生成更快的平面表驱动 FSM
在动作执行代码中。
-G0 (C/D/C#/Go) 生成一个 goto 驱动的 FSM。 goto 驱动的 FSM 代表状态
machine 作为一系列 goto 语句。 在机器中时,当前状态为
由处理器的指令指针存储。 执行是一个平面函数
使用 goto 将控制从一个状态传递到另一个状态。 一般来说,转到 FSM
生成更快的代码,但导致更大的二进制文件和更昂贵的主机
语言编译。
-G1 (C/D/C#/Go) 通过在
动作执行代码。
-G2 (C/D/Go) 通过将动作列表嵌入到
状态机控制代码。
-P (C/D) N-Way Split 非常快的 goto-driven FSM。
雷格 INPUT
注意:这是对 Ragel 输入的非常简短的描述。 更详细地描述了Ragel
在主页上的用户指南中(见下文)。
Ragel 通常将输入文件直接传递给输出。 当它看到 FSM 时
包含机器实例的规范,它停止生成状态机。
如果有写语句(例如“write exec”),那么 ragel 发出相应的
代码。 输入文件中可以有任意数量的 FSM 规范。 多线 FSM
规范以“%%{”开头,以“}%%”结尾。 单行 FSM 规范
以 %% 开始并在第一个换行符处结束。
FSM 声明
机械/机器 名称:
设置机器名称。 如果给出,它必须是第一个语句。
字母 类型:
设置字母表的数据类型。
获取密钥:
指定如何从元素类型中检索字母字符。
包括:
包括与当前名称相同或不同名称的机器
当前文件或其他文件。
操作 定义:
定义可由 FSM 调用的操作。
FSM 定义, 实例化 和 最长 匹配 实例化:
用于构建 FSM。 接下来几节中的语法说明。
权限:
指定如何访问持久状态机变量。
写: 编写机器的一些组件。
变量:
覆盖默认变量名称(p、pe、cs、act 等)。
基本 机
基本机器是正则语言表达式的基本操作数。
'你好'
连接文字。 产生字符串中字符的串联。 支持
使用“\”转义序列。 结果将有一个开始状态和过渡到
字符串中每个字符的新状态。 序列中的最后一个状态将
定为最终。 要使字符串不区分大小写,请在字符串后附加一个“i”,如
在'cmd'i中。
“你好”
与单引号版本相同。
[你好]
或者字面意思。 产生字符的联合。 支持带有“-”的字符范围,
用初始的 '^' 否定联合的意义,用 '\' 转义序列。
结果将有两个状态,每个字符在它们之间有一个转换
或范围。
注意:''、"" 和 [] 产生空 FSM。 空机器有一个既是开始的状态
状态和最终状态并匹配零长度字符串。 可能会创建一个空机器
使用 null 内置机器。
整数
在给定的整数上创建一个具有一个转换的两个状态机。
十六进制 在给定的十六进制数上创建一个具有一个转换的两个状态机。
/简单正则表达式/
一个简单的正则表达式。 支持符号 '.'、'*' 和 '[]',字符
'-' 范围,否定 OR 表达式的意义和初始 '^' 和
使用“\”转义序列。 还支持一个尾随标志:i. 用它来制作一个
不区分大小写的正则表达式,如 /GET/i。
床 .. 床
指定范围。 允许的上限和下限是
长度为一和数字机器。 例如,0x10..0x20、0..63 和 'a'..'z' 是
有效范围。
变量名
引用分配给给定变量名称的机器定义。
内置机器
有几种内置机器可用。 它们都是两个状态机
匹配常见字符类的目的。 他们是:
任何 字母表中的任何字符。
ASCII Ascii 字符 0..127。
延长 Ascii 扩展字符。 这是有符号字母的范围 -128..127
以及无符号字母的范围 0..255。
阿尔法 字母字符 /[A-Za-z]/.
数字 数字 /[0-9]/.
名册 字母数字 /[0-9A-Za-z]/.
降低 小写字符 /[az]/.
上 大写字符 /[AZ]/.
数字 十六进制数字 /[0-9A-Fa-f]/.
控制中心 控制字符 0..31。
图形 图形字符 /[!-~]/.
打印 可打印字符 /[ -~]/.
点 标点。 非字母数字的图形字符
/[!-/:-@\[-`{-~]/.
空间 空格 /[\t\v\f\n\r ]/.
空 零长度字符串。 等价于''、“”和[]。
空的 空集。 什么都不匹配。
简要 操作员 参考
运算符按优先级分组,第 1 组最低,第 6 组最高。
公司 1:
表达式 , 表达式
将机器连接在一起,无需绘制任何转换、设置启动状态或
任何最终状态。 必须使用“开始”标签明确指定开始状态。
最终状态可以通过 epsilon 转换到隐式指定
创建了“最终”状态。
公司 2:
表达式 | 表达式
生成与机器一或机器二中的任何字符串匹配的机器。
表达式 & 表达式
产生一台机器,匹配机器一和机器中的任何字符串
二。
表达式 - 表达式
产生一台机器,它匹配机器一中但不匹配的任何字符串
机器二。
表达式 -- 表达式
强减法。 匹配第一台机器中没有任何字符串的任何字符串
在机器二中作为子串。
公司 3:
表达式 . 表达式
产生一台机器,匹配机器一中的所有字符串,然后是所有的
机器二中的字符串。
表达式 :> 表达式
Entry-Guarded Concatenation:在进入机器 XNUMX 时终止机器 XNUMX。
表达式 :>> 表达式
Finish-Guarded Concatenation:当机器 XNUMX 完成时终止机器 XNUMX。
表达式 <: 表达式
Left-Guarded Concatenation:给机器一个更高的优先级。
注意:连接是默认运算符。 两台机器相邻,没有
它们之间的运算符导致连接操作。
公司 4:
标签: 表达式
将标签附加到表达式。 标签可以被 epsilon 转换和
动作中的 fgoto 和 fcall 语句。 另请注意,机器的引用
定义导致隐式创建同名标签。
公司 5:
表达式 -> 标签
绘制一个 epsilon 转换到标签定义的状态。 标签必须是名称
当前范围。 Epsilon 转换在使用逗号运算符时得到解决
求值并位于机器表达式树的根部
赋值/实例化。
公司 6: 行动
动作可以是用动作语句预定义的名称,也可以直接指定
在表达式中使用 '{' 和 '}'。
表达式 > 行动
将动作嵌入开始过渡。
表达式 @ 行动
将动作嵌入到进入最终状态的转换中。
表达式 $ 行动
将动作嵌入到所有过渡中。 不包括挂起的过渡。
表达式 % 行动
将动作嵌入到最终状态的未决转换中。
公司 6: EOF 行动
当调用机器的完成例程时,将执行当前状态的 EOF 操作。
表达式 >/ 行动
将 EOF 操作嵌入到开始状态。
表达式 </ 行动
将 EOF 操作嵌入到除开始状态之外的所有状态中。
表达式 $/ 行动
将 EOF 操作嵌入所有状态。
表达式 %/ 行动
将 EOF 操作嵌入到最终状态中。
表达式 @/ 行动
将 EOF 操作嵌入所有非最终状态。
表达式 <>/ 行动
将 EOF 操作嵌入到所有不是开始状态和不是开始状态的状态中
最终(中间状态)。
公司 6: 全球 误差 行动
全局错误动作存储在状态中,直到最终状态机完全
建。 然后它们被转移到错误转换,给出一个
默认操作。
表达式 >! 行动
将全局错误操作嵌入到开始状态。
表达式 <! 行动
将全局错误操作嵌入到除开始状态之外的所有状态中。
表达式 $! 行动
将全局错误操作嵌入所有状态。
表达式 %! 行动
将全局错误操作嵌入到最终状态中。
表达式 @! 行动
将全局错误操作嵌入到所有非最终状态中。
表达式 <>! 行动
将全局错误操作嵌入到所有不是开始状态并且是
不是最终的(中间状态)。
公司 6: 本地品牌 误差 行动
本地错误操作存储在状态中,直到完全构造命名机器。
然后它们被转移到错误转换,给出默认操作的效果
总机的一部分。 请注意,名称可以省略,在这种情况下
在构建当前机器时,action 将转换为错误 action。
表达式 >^ 行动
将本地错误操作嵌入到开始状态。
表达式 <^ 行动
将本地错误操作嵌入到除开始状态之外的所有状态中。
表达式 $^ 行动
将本地错误操作嵌入所有状态。
表达式 %^ 行动
将本地错误操作嵌入到最终状态中。
表达式 @^ 行动
将本地错误操作嵌入到所有非最终状态中。
表达式 <>^ 行动
将本地错误操作嵌入到所有不是开始状态并且是
不是最终的(中间状态)。
公司 6: 到状态 行动
状态动作存储在状态中,并在机器进入某个状态时随时执行
状态。 这包括常规转换和控制权转移,例如 fgoto。 笔记
从机器外部设置当前状态(例如在
初始化)不算作状态转换。
表达式 >~ 行动
将一个状态动作动作嵌入到开始状态中。
表达式 <~ 行动
将一个状态动作嵌入到除开始状态之外的所有状态中。
表达式 $~ 行动
将一个状态动作嵌入到所有状态中。
表达式 %~ 行动
将一个状态动作嵌入到最终状态中。
表达式 @~ 行动
将一个状态动作嵌入到所有非最终状态中。
表达式 <>~ 行动
将一个to-state action嵌入到所有不是开始状态和不是开始状态的状态中
最终(中间状态)。
公司 6: 来自状态 行动
每当状态对角色进行转换时,就会执行从状态动作。 这个
包括错误转换和到自身的转换。
表达式 >* 行动
将来自状态的动作嵌入到开始状态。
表达式 <* 行动
将来自状态的动作嵌入到除开始状态之外的每个状态中。
表达式 $* 行动
将来自状态的动作嵌入所有状态。
表达式 %* 行动
将来自状态的动作嵌入到最终状态中。
表达式 @* 行动
将来自状态的动作嵌入到所有非最终状态中。
表达式 <>* 行动
将来自状态的动作嵌入到所有不是开始状态且不是开始状态的状态中
最终(中间状态)。
公司 6: 优先 转让
优先级被分配给转换中的名称。 只有同名的优先级是
允许互动。 在第一种优先级形式中,名称默认为
分配优先级的机器定义。转换没有默认值
优先事项。
表达式 > INT
在所有离开开始状态的转换中分配优先级 int。
表达式 @ INT
在进入最终状态的所有转换中分配优先级 int。
表达式 $ INT
在所有现有转换中分配优先级 int。
表达式 % INT
在所有挂起的转换中分配优先级 int。
优先级分配的第二种形式允许程序员指定名称
分配优先级,允许交互跨越机器定义边界。
表达式 > (名称,整数)
在离开开始状态的所有转换中将优先级 int 分配给 name。
表达式 @ (姓名, 整数)
在进入最终状态的所有转换中将优先级 int 分配给 name。
表达式 $ (姓名, 整数)
在所有现有转换中将优先级 int 分配给 name。
表达式 % (姓名, 整数)
在所有挂起的转换中将优先级 int 分配给 name。
公司 7:
表达式 * 生产机器的克莱尼星。 匹配零个或多个重复的
机。
表达式 **
最长匹配 Kleene Star。 此版本的 kleene star 将更高的优先级放在
呆在机器里,环绕并重新开始。 这个运算符是
相当于 ( ( expr ) $0 %1 )*。
表达式 ? 产生一台接受给定机器或空字符串的机器。 这个运营商
等价于 ( expr | '' )。
表达式 + 生产与自身 kleen 星连接的机器。 匹配一个或
更多的机器重复。 此运算符等效于 ( expr . expr* )。
表达式 {不是}
产生一个机器,它与 expr 的 n 次重复完全匹配。
表达式 {,n}
产生一个匹配从零到 n 次重复的 expr 的机器。
表达式 {n,}
生成匹配 n 次或多次重复 expr 的机器。
表达式 {n,m}
产生一个匹配 n 到 m 次重复 expr 的机器。
公司 8:
! 表达式 生成一台机器,该机器与给定机器不匹配的任何字符串相匹配。 这个
运算符等效于 ( *extend - expr )。
^ 表达式 字符级否定。 匹配单个不匹配的任何单个字符
字符机表达式
公司 9:
( 表达式 )
强制运算符优先。
价值观 可用 IN 守则 积木
fc 当前字符。 相当于*p。
印刷电路板 指向当前字符的指针。 相当于 p。
毛病 表示当前状态的整数值。
参数 表示目标状态的整数值。
芬特里( )
表示入口点的整数值。
声明 可用 IN 守则 积木
持有; 不要前进到当前字符。 相当于--p;。
执行 ;
将当前字符设置为其他字符。 相当于 p = ( )-1;
转到 ;
跳转到由 定义的机器。
转到 * ;
跳转到给出的入口点. 表达式的计算结果必须为整数
表示状态的值。
下一个 ;
将下一个状态设置为由 定义的入口点。 fnext 语句
不会立即跳转到指定状态。 后面的任何操作代码
语句被执行。
下一个 * ;
将下一个状态设置为由给出的入口点. 表达式必须
评估为表示状态的整数值。
呼叫 ;
调用由 定义的机器。 下一个品格会跳到目标
调用操作的转换。
呼叫 * ;
调用给定的入口点. 下一个品格会跳到目标
调用操作的转换。
烦恼; 返回到最后一个 fcall 所在的转换的目标状态。
断断续续;
保存当前状态并立即跳出机器。
鸣谢
Ragel 由阿德里安·瑟斯顿 (Adrian Thurston) 撰写[电子邮件保护]>. Objective-C 输出
由 Erich Ocean 提供。 D 输出由 Alan West 贡献。 Ruby 输出贡献者
维克多·雨果·博尔哈。 由 Daniel Tang 贡献的 C Sharp 代码生成。 对
Colin Fleming 的 Java 代码生成。 由 Justine Tunney 贡献的 Go 代码生成。
使用 onworks.net 服务在线使用 ragel