gavinhoward / bc

An implementation of the POSIX bc calculator with GNU extensions and dc, moved away from GitHub. Finished, but well-maintained.
https://git.gavinhoward.com/gavin/bc
Other
155 stars 32 forks source link

what function to call for parsing string expressions #83

Open DanielRuf opened 1 week ago

DanielRuf commented 1 week ago

I'm new to C and I try to create a PHP extension of bc with SWIG, but as direct replacement for eval() in PHP.

What is the correct function from the bc code to parse a string and return the calculation result or some error / null when parsing fails?

I tried looking at the code, but didn't find the right one.

gavinhoward commented 1 week ago

I'm not sure what you're asking. bc is a program, not a library, and even though I do have a library, it does not include expression parsing.

Are you wanting a library that can parse bc expressions? Unfortunately, this bc cannot do that, and to do so would require refactoring that I don't have time for.

DanielRuf commented 1 week ago

Understood, so I can not do some bc_parse(some-string-from-stdin) with that and I have to resort to some other solution then.

Where can I find the current logic of the CLI? Maybe I can do something with that.

gavinhoward commented 1 week ago

You are correct.

However, what is easiest depends on what you are trying to do. Do you need the full bc language? Or do you just need simple expressions? Or something else?

If you need the full language, the best solution would be to run bc as a child process and just feed it data.

If you need simple expression parsing, then you could implement the parsing with Lex and Yacc, and then use bcl, the bc library, to do the math.

If you need something else, we can see what might work best.

DanielRuf commented 1 week ago

Or do you just need simple expressions? Or something else?

Just basic calculations like eval(1+2/3*4-5).

If you need the full language, the best solution would be to run bc as a child process and just feed it data.

Unfortunately this brings much overhead, I already tested that with exec("bc ...") in PHP.

If you need simple expression parsing, then you could implement the parsing with Lex and Yacc, and then use bcl, the bc library, to do the math.

This sounds more like what I am looking for, even though I wanted to avoid Yacc.

gavinhoward commented 1 week ago

While refactoring to bring the full bc parser into the library may be too much, I may be able to whip a small expression parser in a few hours.

Do you just need the four basic arithmetic operators? Do you need parentheses? Do you need square root?

Let me know what you need. I may need a week to get it to you.

DanielRuf commented 1 week ago

I will check that and let you know in the next days. At least parentheses are also needed.

If there is at least one function (like sqrt or max) implemened, then I can check the implementation and contribute some of my time to implement more or at least I can help with that.

gavinhoward commented 1 week ago

sqrt() is already builtin; I'll add parsing for it. I can also add parsing for max() and min().

You can see everything that's builtin here.

gavinhoward commented 1 week ago

Ack! I'm sorry! I just had something come up in my personal life that will take a lot of time to resolve!

So despite hoping to help with the parsing, I can't even help with a simple thing anymore.

However, I can point you in the right direction. Use the Shunting-Yard Algorithm like this to make an abstract syntax tree, and then do a post-order traversal.

If you need examples of how to use bcl, then its test code is a good start.

Again, I'm really sorry about this, but I figured it would be better to tell you sooner rather than later.

DanielRuf commented 1 week ago

No problem and thanks for letting me know. I will try to understand and solve it.