Calculator program help

I'm trying to make a simple RPN calculator that reads in regular
expressions from a file and evaluates them to execute code. Currently I
have these regular expressions stored in an array of class objects that
have 2 data objects (1. The regex itself and 2. The block of code that
should be executed when a match is found). An example of one of the read
in regex's is below:

[0-9]+
lambda {|input| $myStack.push(input)}

Now, I get input from the user and compare that string to all the
regular expressions in my array. When a match is found, the code is
evaluated. So far it is working by entering in input one by one. Code
and an example are below.

while input = gets
  for i in 0..$regexArray.length-1
    if ( input =~ Regexp.new($regexArray[i].regex) )
      eval($regexArray[i].code).call(input)
    end
  end
end

Example:
5
4

···

+
print

will give "9" as it should. However, I want to make it so I can enter
input in one line like:
5 4 + print

I've tried matching the input string with the regex with: myMatch =
regex.match(input)
but when I enter a string such as "123 456" only the last part ("456")
is matched when I need to first match the ("123"). Any help would be
appreciated.

--
Posted via http://www.ruby-forum.com/.

If your valid expressions contain no whitespace, you can split your input into individual tokens with split(/\s+/). As a minimal example, this works fine:

q =
a = {
  /\d+/ => ->(input) { q << input.to_i },
  /\+|-/ => ->(op) { q.push(q.pop(2).reverse.reduce(op)) },
  /print/ => ->(match) { puts q.pop }
}

DATA.each_line do |input|
  input.split(/\s+/).each do |token|
    code = a[a.keys.detect { |k| token =~ k }]
    code.call(token) unless code.nil?
  end
end

__END__
5 4 + print
5 4 - print

Returns 9 and -1.

If you need to parse more complex input on each line, you should use StringScanner available in the standard library (require 'strscan').

···

On Nov 14, 2011, at 10:23 PM, Trevor Daniels wrote:

I'm trying to make a simple RPN calculator that reads in regular
expressions from a file and evaluates them to execute code. Currently I
have these regular expressions stored in an array of class objects that
have 2 data objects (1. The regex itself and 2. The block of code that
should be executed when a match is found). An example of one of the read
in regex's is below:

[0-9]+
lambda {|input| $myStack.push(input)}

Now, I get input from the user and compare that string to all the
regular expressions in my array. When a match is found, the code is
evaluated. So far it is working by entering in input one by one. Code
and an example are below.

while input = gets
for i in 0..$regexArray.length-1
   if ( input =~ Regexp.new($regexArray[i].regex) )
     eval($regexArray[i].code).call(input)
   end
end
end

Example:
5
4
+
print

will give "9" as it should. However, I want to make it so I can enter
input in one line like:
5 4 + print

I've tried matching the input string with the regex with: myMatch =
regex.match(input)
but when I enter a string such as "123 456" only the last part ("456")
is matched when I need to first match the ("123"). Any help would be
appreciated.

-----Messaggio originale-----

···

Da: Trevor Daniels [mailto:socomcrazy10@yahoo.com]
Inviato: lunedì 14 novembre 2011 22:24
A: ruby-talk ML
Oggetto: calculator program help

I'm trying to make a simple RPN calculator that reads in regular expressions
from a file and evaluates them to execute code. Currently I have these
regular expressions stored in an array of class objects that have 2 data
objects (1. The regex itself and 2. The block of code that should be
executed when a match is found). An example of one of the read in regex's is
below:

[0-9]+
lambda {|input| $myStack.push(input)}

Now, I get input from the user and compare that string to all the regular
expressions in my array. When a match is found, the code is evaluated. So
far it is working by entering in input one by one. Code and an example are
below.

while input = gets
  for i in 0..$regexArray.length-1
    if ( input =~ Regexp.new($regexArray[i].regex) )
      eval($regexArray[i].code).call(input)
    end
  end
end

Example:
5
4
+
print

will give "9" as it should. However, I want to make it so I can enter input
in one line like:
5 4 + print

I've tried matching the input string with the regex with: myMatch =
regex.match(input)
but when I enter a string such as "123 456" only the last part ("456") is
matched when I need to first match the ("123"). Any help would be
appreciated.

--
Posted via http://www.ruby-forum.com/.

--
Caselle da 1GB, trasmetti allegati fino a 3GB e in piu' IMAP, POP3 e SMTP autenticato? GRATIS solo con Email.it http://www.email.it/f

Sponsor:
Conto Arancio al 4,20%. Zero spese e massima liberta', aprilo in due minuti!
Clicca qui: http://adv.email.it/cgi-bin/foclick.cgi?mid919&d)-12

I've just realized, if you'd expect results 9 and 1 then just skip the #reverse call above :wink:

···

On Nov 15, 2011, at 11:05 AM, Sylvester Keil wrote:

On Nov 14, 2011, at 10:23 PM, Trevor Daniels wrote:

I'm trying to make a simple RPN calculator that reads in regular
expressions from a file and evaluates them to execute code. Currently I
have these regular expressions stored in an array of class objects that
have 2 data objects (1. The regex itself and 2. The block of code that
should be executed when a match is found). An example of one of the read
in regex's is below:

[0-9]+
lambda {|input| $myStack.push(input)}

Now, I get input from the user and compare that string to all the
regular expressions in my array. When a match is found, the code is
evaluated. So far it is working by entering in input one by one. Code
and an example are below.

while input = gets
for i in 0..$regexArray.length-1
  if ( input =~ Regexp.new($regexArray[i].regex) )
    eval($regexArray[i].code).call(input)
  end
end
end

Example:
5
4
+
print

will give "9" as it should. However, I want to make it so I can enter
input in one line like:
5 4 + print

I've tried matching the input string with the regex with: myMatch =
regex.match(input)
but when I enter a string such as "123 456" only the last part ("456")
is matched when I need to first match the ("123"). Any help would be
appreciated.

If your valid expressions contain no whitespace, you can split your input into individual tokens with split(/\s+/). As a minimal example, this works fine:

q =
a = {
  /\d+/ => ->(input) { q << input.to_i },
  /\+|-/ => ->(op) { q.push(q.pop(2).reverse.reduce(op)) },
  /print/ => ->(match) { puts q.pop }
}

DATA.each_line do |input|
input.split(/\s+/).each do |token|
   code = a[a.keys.detect { |k| token =~ k }]
   code.call(token) unless code.nil?
end
end

__END__
5 4 + print
5 4 - print

Returns 9 and -1.

-----Messaggio originale-----

···

Da: Sylvester Keil [mailto:sylvester.keil@gmail.com]
Inviato: martedì 15 novembre 2011 11:05
A: ruby-talk ML
Oggetto: Re: calculator program help

On Nov 14, 2011, at 10:23 PM, Trevor Daniels wrote:

I'm trying to make a simple RPN calculator that reads in regular
expressions from a file and evaluates them to execute code. Currently
I have these regular expressions stored in an array of class objects
that have 2 data objects (1. The regex itself and 2. The block of code
that should be executed when a match is found). An example of one of
the read in regex's is below:

[0-9]+
lambda {|input| $myStack.push(input)}

Now, I get input from the user and compare that string to all the
regular expressions in my array. When a match is found, the code is
evaluated. So far it is working by entering in input one by one. Code
and an example are below.

while input = gets
for i in 0..$regexArray.length-1
   if ( input =~ Regexp.new($regexArray[i].regex) )
     eval($regexArray[i].code).call(input)
   end
end
end

Example:
5
4
+
print

will give "9" as it should. However, I want to make it so I can enter
input in one line like:
5 4 + print

I've tried matching the input string with the regex with: myMatch =
regex.match(input)
but when I enter a string such as "123 456" only the last part ("456")
is matched when I need to first match the ("123"). Any help would be
appreciated.

If your valid expressions contain no whitespace, you can split your input
into individual tokens with split(/\s+/). As a minimal example, this works
fine:

q =
a = {
  /\d+/ => ->(input) { q << input.to_i },
  /\+|-/ => ->(op) { q.push(q.pop(2).reverse.reduce(op)) },
  /print/ => ->(match) { puts q.pop }
}

DATA.each_line do |input|
  input.split(/\s+/).each do |token|
    code = a[a.keys.detect { |k| token =~ k }]
    code.call(token) unless code.nil?
  end
end

__END__
5 4 + print
5 4 - print

Returns 9 and -1.

If you need to parse more complex input on each line, you should use
StringScanner available in the standard library (require 'strscan').

--
Caselle da 1GB, trasmetti allegati fino a 3GB e in piu' IMAP, POP3 e SMTP autenticato? GRATIS solo con Email.it http://www.email.it/f

Sponsor:
Capodanno al parco Oltremare Riccione: Pacchetto hotel 3 stelle in centro + ingresso al parco.
* Mezza pensione, Internet gratis, animazione per bimbi. Scopri l'offerta!
Clicca qui: http://adv.email.it/cgi-bin/foclick.cgi?mid981&d)-12