File: bnf.rb

package info (click to toggle)
ruby-rsec 0.4.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 272 kB
  • sloc: ruby: 2,130; lisp: 13; makefile: 3
file content (31 lines) | stat: -rw-r--r-- 942 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# BNF grammar parser
# http://en.wikipedia.org/wiki/Backus-Naur_form

require "rsec"

include Rsec::Helpers

def bnf
  nbsp      = /[\ \t]*/.r
  spacee    = /\s*/.r # include \n
  literal   = /".*?"|'.*?'/.r
  rule_name = /\<.*?\>/
  term      = literal | rule_name
  list      = term.join(nbsp).even
  expr      = list.join seq(nbsp, '|', nbsp)[1]
  rule      = seq_ rule_name, '::=', expr
  spacee.join(rule).eof
end

require "pp"
pp bnf.parse! DATA.read

__END__
<syntax>     ::= <rule> | <rule> <syntax>
<rule>       ::= <opt-whitespace> "<" <rule-name> ">" <opt-whitespace> "::=" <opt-whitespace> <expression> <line-end>
<opt-whitespace> ::= " " <opt-whitespace> | ""
<expression> ::= <list> | <list> "|" <expression>
<line-end>   ::= <opt-whitespace> <EOL> | <line-end> <line-end>
<list>       ::= <term> | <term> <opt-whitespace> <list>
<term>       ::= <literal> | "<" <rule-name> ">"
<literal>    ::= '"' <text> '"' | "'" <text> "'"