Dou*_*ers 5 ruby parsing lex erb
我试图以 Hpricot/Nokogiri 类型的方式解析而不是评估 rails ERB 文件。我试图解析的文件包含与使用 ERB(标准 Rails 视图文件)生成的动态内容混合的 HTML 片段ERB 符号、<%、<%= 等,就好像它们是 html/xml 标签一样。
理想情况下,我会得到一个类似于 DOM 的结构,其中 <%, <%= 等符号将作为它们自己的节点类型包含在内。
我知道可以使用正则表达式将某些东西组合在一起,但我正在寻找更可靠的东西,因为我正在开发一个工具,我需要在一个非常大的视图代码库上运行,其中 html 内容和 erb 内容是重要的。
例如,内容如下:
等等等等等等 <div>我的好文字 <%= my_dynamic_expression %></div>
将返回一个树结构,如:
根
- text_node(等等等等)
- 元素(div)
- text_node(我的好文字)
- erb_node (<%=)
我最终通过使用 RLex 解决了这个问题,http: //raa.ruby-lang.org/project/ruby-lex/,lex的 ruby 版本,具有以下语法:
%{
#define NUM 257
#define OPTOK 258
#define IDENT 259
#define OPETOK 260
#define CLSTOK 261
#define CLTOK 262
#define 浮点数 263
#define FIXNUM 264
#定义字265
#define STRING_DOUBLE_QUOTE 266
#define STRING_SINGLE_QUOTE 267
#define TAG_START 268
#define TAG_END 269
#define TAG_SELF_CONTAINED 270
#define ERB_BLOCK_START 271
#define ERB_BLOCK_END 272
#define ERB_STRING_START 273
#define ERB_STRING_END 274
#define TAG_NO_TEXT_START 275
#define TAG_NO_TEXT_END 276
#define WHITE_SPACE 277
%}
数字 [0-9]
空白的 [ ]
字母 [A-Za-z]
name1 [A-Za-z_]
name2 [A-Za-z_0-9]
valid_tag_character [A-Za-z0-9"'=@_():/]
ignore_tags 样式|脚本
%%
{blank}+"\n" { return [ WHITE_SPACE, yytext ] }
"\n"{blank}+ { return [ WHITE_SPACE, yytext ] }
{blank}+"\n"{blank}+ { return [ WHITE_SPACE, yytext ] }
"\r" { 返回 [ WHITE_SPACE, yytext ] }
"\n" { return[ yytext[0], yytext[0..0] ] };
"\t" { return[ yytext[0], yytext[0..0] ] };
^{空白}+ { 返回 [ WHITE_SPACE, yytext ] }
{blank}+$ { return [ WHITE_SPACE, yytext ] };
"" { 返回 [ TAG_NO_TEXT_START, yytext ] }
"" { 返回 [ TAG_NO_TEXT_END, yytext ] }
"" { 返回 [ TAG_SELF_CONTAINED, yytext ] }
"" { 返回 [ TAG_SELF_CONTAINED, yytext ] }
"" { 返回 [ TAG_START, yytext ] }
"" { 返回 [ TAG_END, yytext ] }
"" { 返回 [ ERB_BLOCK_END, yytext ] }
"" { 返回 [ ERB_STRING_END, yytext ] }
{letter}+ { return [ WORD, yytext ] }
\".*\" { 返回 [ STRING_DOUBLE_QUOTE, yytext ] }
'.*' { 返回 [ STRING_SINGLE_QUOTE, yytext ] }
. { 返回 [ yytext[0], yytext[0..0] ] }
%%
这不是一个完整的语法,但就我的目的而言,定位和重新发送文本,它起作用了。我将语法与这段代码结合起来:
text_handler = MakeYourOwnCallbackHandler.new
l = Erblex.new
l.yyin = File.open(file_name, "r")
循环做
a,v = l.yylex
如果 a == 0 则中断
if( a < 字 )
text_handler.character( v.to_s, a )
别的
案例一
当 WORD
text_handler.text( v.to_s )
当 TAG_START
text_handler.start_tag( v.to_s )
当TAG_END
text_handler.end_tag( v.to_s )
当空格
text_handler.white_space( v.to_s )
当 ERB_BLOCK_START
text_handler.erb_block_start( v.to_s )
当 ERB_BLOCK_END
text_handler.erb_block_end( v.to_s )
当 ERB_STRING_START
text_handler.erb_string_start( v.to_s )
当 ERB_STRING_END
self.text_handler.erb_string_end( v.to_s )
当 TAG_NO_TEXT_START
text_handler.ignorable_tag_start( v.to_s )
当TAG_NO_TEXT_END
text_handler.ignorable_tag_end( v.to_s )
当STRING_DOUBLE_QUOTE
text_handler.string_double_quote( v.to_s )
当STRING_SINGLE_QUOTE
text_handler.string_single_quote( v.to_s )
当 TAG_SELF_CONTAINED
text_handler.tag_self_contained( v.to_s )
结尾
结尾
结尾
| 归档时间: |
|
| 查看次数: |
2896 次 |
| 最近记录: |