Class: RDParser
- Inherits:
-
Object
- Object
- RDParser
- Defined in:
- lib/asciitracker/rdparser.rb
Overview
Subject: ***Re: [SOLUTION] Dice Roller (#61)* From: *Dennis Ranke *<mail exoticorn.de> Date: Mon, 9 Jan 2006 06:53:10 +0900 References: 174521 </cgi-bin/scat.rb/ruby/ruby-talk/174521> 174811 </cgi-bin/scat.rb/ruby/ruby-talk/174811> In-reply-to: 174811 </cgi-bin/scat.rb/ruby/ruby-talk/174811>
Hi,
here is my second solution. Quite a bit longer, but a lot nicer. For this I implemented a simple recursive descent parser class that allows the tokens and the grammar to be defined in a very clean ruby syntax. I think I’d really like to see a production quality parser(generator) using something like this grammar format.
Defined Under Namespace
Instance Attribute Summary collapse
-
#pos ⇒ Object
Returns the value of attribute pos.
-
#rules ⇒ Object
readonly
Returns the value of attribute rules.
Instance Method Summary collapse
- #expect(tok) ⇒ Object
-
#initialize(&block) ⇒ RDParser
constructor
A new instance of RDParser.
- #next_token ⇒ Object
- #parse(string) ⇒ Object
Constructor Details
#initialize(&block) ⇒ RDParser
Returns a new instance of RDParser.
22 23 24 25 26 27 |
# File 'lib/asciitracker/rdparser.rb', line 22 def initialize(&block) @lex_tokens = [] @rules = {} @start = nil instance_eval(&block) end |
Instance Attribute Details
#pos ⇒ Object
Returns the value of attribute pos.
19 20 21 |
# File 'lib/asciitracker/rdparser.rb', line 19 def pos @pos end |
#rules ⇒ Object (readonly)
Returns the value of attribute rules.
20 21 22 |
# File 'lib/asciitracker/rdparser.rb', line 20 def rules @rules end |
Instance Method Details
#expect(tok) ⇒ Object
64 65 66 67 68 69 70 71 72 73 |
# File 'lib/asciitracker/rdparser.rb', line 64 def expect(tok) t = next_token if @pos - 1 > @max_pos @max_pos = @pos - 1 @expected = [] end return t if tok === t @expected << tok if @max_pos == @pos - 1 && !@expected.include?(tok) return nil end |
#next_token ⇒ Object
59 60 61 62 |
# File 'lib/asciitracker/rdparser.rb', line 59 def next_token @pos += 1 return @tokens[@pos - 1] end |
#parse(string) ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/asciitracker/rdparser.rb', line 29 def parse(string) @tokens = [] until string.empty? raise "unable to lex '#{string}" unless @lex_tokens.any? do |tok| #puts "match(#{string}) <- (#{tok})" match = tok.pattern.match(string) if match s_tok = match.to_s puts "(#{s_tok})" unless /^\s+$/.match(s_tok) #puts "<<< #{s_tok} | #{tok.pattern} >>>" @tokens << tok.block.call(s_tok) if tok.block string = match.post_match #puts "<<<#{s_tok}|||#{match.post_match}>>>" true else false end end end @pos = 0 @max_pos = 0 @expected = [] result = @start.parse if @pos != @tokens.size raise "Parse error. expected: '#{@expected.join(', ')}', found '#{@tokens[@max_pos]}'" end return result end |