[英]Are Ruby 1.9 regular expressions equally powerful to a context free grammar?
我有這個正則表達式:
regex = %r{\A(?<foo> a\g<foo>a | b\g<foo>b | c)\Z}x
當我針對幾個字符串測試它時,它看起來像上下文無關語法一樣強大,因為它正確處理遞歸。
regex.match("aaacaaa")
# => #<MatchData "aaacaaa" foo:"aaacaaa">
regex.match("aacaa")
# => #<MatchData "aacaa" foo:"aacaa">
regex.match("aabcbaa")
# => #<MatchData "aabcbaa" foo:"aabcbaa">
regex.match("aaacaa")
# => nil
“ Ruby 1.9正則表達式的樂趣 ”有一個例子,他實際上安排了一個正則表達式的所有部分,使它看起來像一個無上下文的語法,如下所示:
sentence = %r{
(?<subject> cat | dog | gerbil ){0}
(?<verb> eats | drinks| generates ){0}
(?<object> water | bones | PDFs ){0}
(?<adjective> big | small | smelly ){0}
(?<opt_adj> (\g<adjective>\s)? ){0}
The\s\g<opt_adj>\g<subject>\s\g<verb>\s\g<opt_adj>\g<object>
}x
在他重新排列正則表達式部分的技術和我的遞歸命名捕獲組的例子之間,這是否意味着Ruby 1.9正則表達式具有與無上下文語法相當的能力?
這是關於Ruby 1.9中使用的Oniguruma regexp引擎的一個很棒的東西 - 它具有解析器的強大功能,並且不限於識別常規語言。 它具有正面和負面的前瞻/外觀,甚至可以用來識別一些不具有上下文的語言! 以下面的例子為例:
regexp = /\A(?<AB>a\g<AB>b|){0}(?=\g<AB>c)a*(?<BC>b\g<BC>c|){1}\Z/
此正則表達式識別“abc”,“aabbcc”,“aaabbbcc”等字符串 - “a”,“b”和“c”的數量必須相等,否則它們將不匹配。
(一個限制:你不能在前瞻和后方使用命名組。)
雖然我沒有偷看,但Oniguruma似乎通過簡單的遞歸下降處理命名組,當事情不匹配時備份。 我觀察到它不能處理左遞歸。 例如:
irb(main):013:0> regexp = /(?<A>\g<A>a|)/
SyntaxError: (irb):13: never ending recursion: /(?<A>\g<A>a|)/
from C:/Ruby192/bin/irb:12:in `<main>'
我不太清楚地記得我的解析理論,但我認為像這樣的非確定性自上而下的解析器應該能夠解析任何無上下文的語言。 (“語言”,而不是“語法”;如果您的語法已經離開遞歸,則必須將其轉換為正確的遞歸。)如果這不正確,請編輯此帖子。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.