From: "Luca (Email)" Date: 2011-12-29T15:50:05+09:00 Subject: I: calculator program help -----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