Created
April 29, 2012 04:22
-
-
Save lnznt/2533003 to your computer and use it in GitHub Desktop.
sample: 'hello world' parser (Ruby/Racc)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding : UTF-8 -*- | |
# | |
# to generate 'hello_parser.rb' | |
# | |
# $ racc -o hello_parser.rb hello_parser.ry | |
# | |
# to execute | |
# | |
# $ ruby hello_parser.rb <<EOT | |
# hello world #=> OK(1) | |
# EOT | |
# | |
# $ ruby hello_parser.rb <<EOT | |
# Hello, World #=> OK(2) | |
# EOT | |
# | |
# $ ruby hello_parser.rb <<EOT | |
# Hello: World # Racc::ParseError | |
# EOT | |
# | |
class HelloParser | |
rule | |
message : HELLO WORLD EOL { puts "OK(1)" ; result = val.join } | |
| HELLO ',' WORLD EOL { puts "OK(2)" ; result = val.join } | |
end | |
---- header | |
require 'strscan' | |
---- inner | |
attr_accessor :yydebug | |
def parse(text) | |
s = StringScanner.new text | |
tokens = [] | |
case | |
when s.scan(/hello\b/i) ; tokens << [:HELLO, s.matched] | |
when s.scan(/world\b/i) ; tokens << [:WORLD, s.matched] | |
when s.scan(/\n/) ; tokens << [:EOL, s.matched] | |
when s.scan(/\s/) ; # ignore white space | |
when s.scan(/./m) ; tokens << [s.matched, s.matched] | |
end until s.eos? | |
define_singleton_method(:next_token) { tokens.shift } | |
do_parse | |
end | |
---- footer | |
if __FILE__ == $0 | |
require 'optparse' | |
parser = HelloParser.new | |
ARGV.options do |opt| | |
opt.on('-d', '--debug') { parser.yydebug = true } | |
opt.parse! | |
end | |
parser.parse ARGF.read | |
end | |
# vi:set ts=2 sw=2 et: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding : UTF-8 -*- | |
# | |
# to generate 'hello_parser2.rb' | |
# | |
# $ racc -o hello_parser2.rb hello_parser2.ry | |
# | |
# to execute | |
# | |
# $ ruby hello_parser2.rb <<EOT | |
# hello world #=> OK(1) | |
# EOT | |
# | |
# $ ruby hello_parser2.rb <<EOT | |
# Hello, World #=> OK(2) | |
# EOT | |
# | |
# $ ruby hello_parser2.rb <<EOT | |
# Hello: World # Racc::ParseError | |
# EOT | |
# | |
class HelloParser | |
rule | |
message : | |
| message helloworld { result = val.join } | |
helloworld : HELLO WORLD EOL { puts "OK(1)" ; result = val.join } | |
| HELLO ',' WORLD EOL { puts "OK(2)" ; result = val.join } | |
end | |
---- header | |
require 'strscan' | |
---- inner | |
attr_accessor :yydebug | |
def parse(text="", &source) | |
@source = source || proc {} | |
@s = StringScanner.new text | |
do_parse | |
end | |
class SkipToken < RuntimeError ; end | |
def next_token | |
@s << (@source.call or raise EOFError) if @s.eos? | |
case | |
when @s.scan(/hello\b/i) ; [:HELLO, @s.matched] | |
when @s.scan(/world\b/i) ; [:WORLD, @s.matched] | |
when @s.scan(/\n/) ; [:EOL, @s.matched] | |
when @s.scan(/\s/) ; raise SkipToken | |
when @s.scan(/./m) ; [@s.matched, @s.matched] | |
end | |
rescue SkipToken | |
retry | |
rescue EOFError | |
nil | |
end | |
---- footer | |
if __FILE__ == $0 | |
require 'optparse' | |
parser = HelloParser.new | |
ARGV.options do |opt| | |
opt.on('-d', '--debug') { parser.yydebug = true } | |
opt.parse! | |
end | |
parser.parse { ARGF.gets } | |
end | |
# vi:set ts=2 sw=2 et: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/make -f | |
# -*- coding: UTF-8 -*- | |
# | |
# to generate 'foo.rb' from 'foo.ry' | |
# | |
# ex.1) $ make foo.rb | |
# | |
# ex.2) $ make FLAGS=-C foo.rb # syntax check only | |
# | |
# see also 'racc --help' | |
RACCFLAGS += --debug # -t | |
#RACCFLAGS += --verbose # -v | |
#RACCFLAGS += --log-file=filename # -Ofilename | |
#RACCFLAGS += --execute=ruby # -erubypath | |
#RACCFLAGS += --embedded # -E | |
#RACCFLAGS += --line-convert-all | |
#RACCFLAGS += --no-line-convert # -l | |
#RACCFLAGS += --no-omit-actions # -a | |
#RACCFLAGS += --superclass=CLASSNAME | |
#RACCFLAGS += --runtime=FEATURE | |
#RACCFLAGS += --check-only # -C | |
#RACCFLAGS += --output-status # -S | |
#RACCFLAGS += --output-status # -S | |
#RACCFLAGS += -P | |
RACCFLAGS += ${FLAGS} | |
%.rb: %.ry | |
racc ${RACCFLAGS} -o $@ $< | |
.PHONY : all | |
# | |
# to generate 'hello_parser.rb' | |
# | |
# ex.1) $ make | |
# | |
# ex.2) $ make FLAGS=-C # syntax check only | |
# | |
all : hello_parser.rb | |
# vi:set ts=4 sw=4: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment