I'm trying to evaluate an arithmetic operation of prefix type, "add(multiply(123,432),subtract(add(19,21),124))", can you make it so the regex engine scans it backwards? I'm trying to isolate each word and manipulate it without using split() and creating another array of o(n) space. I can parse the string from end to start by character and tokenize it using string index, but there must be someway to do this using regex efficiently. I know that split() creates an array that can be traversed backwards, but is there anyway to bypass the extra space required by split()? (Does the ruby interpreter/compiler somehow handle it?) Ultimately, is there anyway to make scan() parse a string backwards? Thanks

on 2014-02-09 12:43

on 2014-02-10 04:30

You need to show what code you have currently.

on 2014-02-10 13:35

On Sun, Feb 9, 2014 at 12:43 PM, Tonton San <lists@ruby-forum.com> wrote: > I'm trying to evaluate an arithmetic operation of prefix type, > "add(multiply(123,432),subtract(add(19,21),124))", can you make it so > the regex engine scans it backwards? Note Ruby's regexp engine since 1.9 can parse nested structures (i.e. non regular languages but context free languages). You'll find some hints here http://www.geocities.jp/kosako3/oniguruma/doc/RE.txt > > Ultimately, is there anyway to make scan() parse a string backwards? No. You can reverse the String but then you also have to reverse the regexp which is not trivial for all cases. Kind regards robert

on 2014-02-10 16:10

Tonton San wrote in post #1136122: > I'm trying to evaluate an arithmetic operation of prefix type, > "add(multiply(123,432),subtract(add(19,21),124))", can you make it so > the regex engine scans it backwards? why scans backward ? s="add(multiply(2,4),substract(add(add(add(1,2),9),add(2,1)),1))" l=s.split(/([)(,\-])/).reject {|a| a=='(' || a==')' || a==',' || a==""} p l reg=[] def add(a,b) (a.to_i+b.to_i).to_s end def multiply(a,b) (a.to_i*b.to_i).to_s end def substract(a,b) (b.to_i-a.to_i).to_s end def is_num(a) a=~/^-?\d+$/ end def is_op(a) a=~/^[a-z]+$/ end loop do if is_num(l[-1]) && is_num(l[-2]) && is_op(l[-3]) a,b,op=l.pop,l.pop,l.pop l.push send(op,a,b) end if is_num(l[-1]) && is_num(l[-2]) && is_num(l[-3]) reg << l.pop end if is_num(l[-1]) && is_op(l[-2]) && reg.size>0 l.push reg.pop end puts "#{l.inspect} || #{reg.inspect}" break if l.size==1 && reg.size==0 end p l.last Perhaps you mix lexical analysis with syntax analysis and evaluator ?