Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.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
Ruby Whittle解析器条件规则激活_Ruby_Regex_Parsing - Fatal编程技术网

Ruby Whittle解析器条件规则激活

Ruby Whittle解析器条件规则激活,ruby,regex,parsing,Ruby,Regex,Parsing,我正在使用解析模板语言,并希望匹配规则中未包含的任何内容。我很了解其他模板引擎,但这更多的是一个学术练习,而不是一个生产案例 我遇到的问题是解析器忽略了:id在:raw之上的优先级,仍然在{{之后等待:raw标记 如何告诉解析器不允许在表达式中应用:raw规则,而只允许在表达式中应用:spc规则 解析器代码 class Parser < Whittle::Parser # Skip whitespaces (should not apply in :raw) rule(:s

我正在使用解析模板语言,并希望匹配规则中未包含的任何内容。我很了解其他模板引擎,但这更多的是一个学术练习,而不是一个生产案例

我遇到的问题是解析器忽略了
:id
:raw
之上的优先级,仍然在
{{
之后等待
:raw
标记

如何告诉解析器不允许在表达式中应用
:raw
规则,而只允许在表达式中应用
:spc
规则

解析器代码

class Parser < Whittle::Parser
    # Skip whitespaces (should not apply in :raw)
    rule(:spc => /\s+/).skip!

    # Various delimiters
    rule("{{") ^ 4
    rule("}}") ^ 4
    rule("{%") ^ 4
    rule("%}") ^ 4
    rule("|") ^ 4
    rule("end") ^ 4

    # Defines an id (very large match)
    rule(:id => /[a-zA-Z_.$<>=!:]+(\((\w+|\s+|,|")+\))?/) ^ 2

    # inline tag
    rule(:inline) do |r|
        r["{{", :inline_head, "}}"].as { |_,id,_| Tag::Inline.new(id) }
    end
    # inline tag contents
    # allows "|" chaining
    rule(:inline_head) do |r|
        r[:inline_head, "|", :id].as { |head, _, id| head << id }
        r[:id].as { |id| [id] }
        r[].as { [] }
    end

    # block tag
    rule(:block) do |r|
        r["{%", :block_head, "%}", :all, "{%", "end", "%}"].as { |_,head,_,tags,_,_,_|
            Tag::Block.new(head, tags)
        }
    end
    # block tag heading
    # separates all the keywords
    rule(:block_head) do |r|
        r[:block_head, :id].as { |head, id| head << id }
        #r[:id].as { |id| [id] }
        r[].as { [] }
    end

    # one rule to match them all
    rule(:all) do |r|
        r[:all,:inline].as { |all, inline| all << inline }
        r[:all, :block].as { |all, block| all << block }
        r[:all, :raw].as { |all, raw| all << raw }
        r[].as { [] }
    end

    # the everything but tags rule
    rule(:raw => /[^\{\}%]+/).as { |text| Tag::Raw.new(text) } ^ 1

    # starting rule
    start(:all)
end
类解析器/\s+/)。跳过!
#各种分隔符
规则(“{”)^4
规则(“}”)^4
规则(“{%”)^4
规则(“%}”)^4
规则(“|”)^4
规则(“结束”)^4
#定义一个id(非常大的匹配)
规则(:id=>/[a-zA-Z.$=!:]+(\((\w+\s+\s+,“)”+\)?/)^2
#内联标签
规则(:inline)do|r|
r[{{,:inline_head,}}}].as{{{124;},id,{124; Tag::inline.new(id)}
结束
#内联标记内容
#允许“|”链接
规则(:inline_head)do|r|

r[:inline_head,“|”,:id]。作为{head,|,id | head我不认为运算符优先级支持在这里起作用。运算符优先级仅在解决表达式(如
foo=6+7
)中的歧义时起作用,其中表达式可以解释为
(foo=6)+7
foo=(6+7)
。赋予非运算符优先级实际上没有任何作用

也许还不清楚解析器的实际功能。它基本上是重复循环的,将所有终端规则与输入字符串匹配。对于找到的规则,它使用最长的一个,并尝试在当前状态下找到一个适合它的规则。因此解析器将始终找到您的空白并丢弃它,因为这是第一个r你的语法有问题

我认为你实际上不想跳过空格,因为它在你的语法中很重要。你想把它包括在你的规则中,这样会使你的语法更加冗长,但(目前)是不可避免的

因此,
:raw
变得类似于以下内容,将所有空白和非语法标记吞并到一个字符串中:

rule(:raw => /[^\s\{\}%]+/)

rule(:text) do |r|
  r[:text, :raw].as { |text, raw| text << raw }
  r[:text, :spc].as { |text, spc| text << spc }
  r[:spc]
  r[:raw]
end

我一直在考虑如何提供在不同状态下匹配不同令牌的能力,但我担心编写lex/flex的克隆,我认为这太令人困惑了,因此我尝试提出一种方法,使用块在彼此内部嵌套规则来传达状态之间的关系;尽管这并不简单创建一个易于理解的DSL来实现这一点;)我还想提供一个可选的DSL来隐藏用于重复的算法;可能提供一种PEG层来转换为LR解析器。这仍然是一个(非常)young project;)

我不认为运算符优先级支持在这里起作用。运算符优先级仅在解决诸如
foo=6+7
之类表达式中的歧义时起作用,其中表达式可以解释为
(foo=6)+7
foo=(6+7)
。赋予非运算符优先级实际上没有任何作用

也许还不清楚解析器的实际功能。它基本上是重复循环的,将所有终端规则与输入字符串匹配。对于找到的规则,它使用最长的一个,并尝试在当前状态下找到一个适合它的规则。因此解析器将始终找到您的空白并丢弃它,因为这是第一个r你的语法有问题

我认为你实际上不想跳过空格,因为它在你的语法中很重要。你想把它包括在你的规则中,这样会使你的语法更加冗长,但(目前)是不可避免的

因此,
:raw
变得类似于以下内容,将所有空白和非语法标记吞并到一个字符串中:

rule(:raw => /[^\s\{\}%]+/)

rule(:text) do |r|
  r[:text, :raw].as { |text, raw| text << raw }
  r[:text, :spc].as { |text, spc| text << spc }
  r[:spc]
  r[:raw]
end

我一直在考虑如何提供在不同状态下匹配不同令牌的能力,但我担心编写lex/flex的克隆,我认为这太令人困惑了,因此我尝试提出一种方法,使用块在彼此内部嵌套规则来传达状态之间的关系;尽管这并不简单创建一个易于理解的DSL来实现这一点;)我还想提供一个可选的DSL来隐藏用于重复的算法;可能提供一种PEG层来转换为LR解析器。这仍然是一个(非常)young project;)

Woah来自作者本人!我正在尽快尝试此功能。感谢您在几次调整后解决了我的所有问题。伟大的项目!Woah来自作者本人!我正在尽快尝试此功能。感谢您在几次调整后解决了我的所有问题。伟大的项目!
rule(:all) do |r|
  # ... snip ...
  r[:all, :text].as { |all, text| all << Tag::Raw.new(text) }
  # ... snip ...
end