# Mini Parser

**URL:** <https://www.ruby-forum.com/t/mini-parser/175988>\
**Category:** Ruby\
**Created:** [September 23, 2009, 11:55am UTC](https://www.ruby-forum.com/t/mini-parser/175988 "2009-09-23T11:55:22Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![karthikb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/a4c791/32.png) [@karthikb](https://www.ruby-forum.com/u/karthikb)\
**Post date:** [September 23, 2009, 11:55am UTC](https://www.ruby-forum.com/t/mini-parser/175988/1 "2009-09-23T11:55:22Z")

</div>

Hi all,

I have a requirement. I have a to read some commands from file and  
output as another file. For example if the input file is like below:

6  
WRITE Today  
WRITE is  
UNDO 1  
WRITE my  
UNDO 2  
WRITE birthday

Output file will be like this.

Today is birthday

WRITE basically write’s string after the command and UNDO will undo N  
number of line preceding it. Complexity here is last UNDO has to UNDO  
the previous undo’s work.

So far I have been able to only come up with the below code:

begin  
file = File.new(“abc.txt”, “r”)  
while (line = file.gets)  
line.grep(/WRITE/) { |s|  
puts s  
}  
end  
file.close

rescue =\> err  
puts “Exception: #{err}”  
err  
end

Any help here?

---

<div class="post-metadata">

**Author:** ![karthikb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/a4c791/32.png) [@karthikb](https://www.ruby-forum.com/u/karthikb)\
**Post date:** [September 23, 2009, 12:24pm UTC](https://www.ruby-forum.com/t/mini-parser/175988/2 "2009-09-23T12:24:20Z")

</div>

On Wed, Sep 23, 2009 at 10:55 AM, Karthikeyan Balasubramanian  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> UNDO 2  
> So far I have been able to only come up with the below code:  
> rescue =\> err  
> puts “Exception: #{err}”  
> err  
> end
> 
> ## Any help here?
> 
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

If you want undoable commands you need to keep a command history. I’d  
check out the Command design pattern if I were you.

–  
Paul S.  
[http://www.nomadicfun.co.uk](http://www.nomadicfun.co.uk)

removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![karthikb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/a4c791/32.png) [@karthikb](https://www.ruby-forum.com/u/karthikb)\
**Post date:** [September 23, 2009, 1:31pm UTC](https://www.ruby-forum.com/t/mini-parser/175988/3 "2009-09-23T13:31:39Z")

</div>

Am Mittwoch 23 September 2009 11:55:24 schrieb Karthikeyan  
Balasubramanian:

> WRITE basically write’s string after the command and UNDO will undo N  
> number of line preceding it. Complexity here is last UNDO has to UNDO  
> the previous undo’s work.

Obviously you need to find out which WRITEs actually execute, before  
producing  
any output, since it’s hard to undo output that’s already been printed  
to the  
screen.

Since there are no conditional statements, you know that all the UNDOs  
will  
execute, so you can execute all the UNDOs in phase 1 and then execute  
the  
WRITEs that haven’t been UNDOne in PHASE 2.

The problem of UNDOing UNDOs can be solved by simply going through the  
UNDOs  
in reverse order.

This should work:

commands = File.readlines(sourcefile).map {|line|  
line.chomp.split(/\s+/, 2)}

commands.reverse!  
undos = 0  
commands.reject! do |command, argument|  
if undos \> 0  
undos -= 1  
true  
elsif command == “UNDO”  
undos = argument.to\_i  
true  
else  
false  
end  
end  
commands.reverse!

commands.each do |command, argument|  
print argument, " "  
end

---

<div class="post-metadata">

**Author:** ![karthikb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/a4c791/32.png) [@karthikb](https://www.ruby-forum.com/u/karthikb)\
**Post date:** [September 23, 2009, 2:24pm UTC](https://www.ruby-forum.com/t/mini-parser/175988/4 "2009-09-23T14:24:03Z")

</div>

This is exactly what I wanted.

Thank you a tons.
