SynthMaker

Expression evaluator

Archive · 2010 5 old posts

From the original SynthMaker forum (2004–2014), with its members’ names and dates.

mwvdlee ·

Today I wanted to know if the custom parser could do recursive rules. Recursive rules are essential if you want to parse anything more trivial than a simple configuration file. Like, for instance, mathematical expressions.

Here's a very early start:

I've you're interrested in parsers in general, you probably know about expression evaluators already. If not; they're a great starting point for learning about parsers, so join in 🙂

Right now I just have a basic parser which recognizes only +, -, parenthesis and ofcourse numbers, in the precendence I learnt in school. Note that it is more common for programming languages to pair up several operators into single precendence levels, i.e. + and -, * and /. The output of this parser is an RPN stack (reverse polish notation, look it up if you're interrested. A.k.a. postfix notation).

The intent is to make a basic expression evaluator based on a simple, easy modifiable grammar, a recursive descent parser and either RPN or shunting-yard as evaluator (I prefer RPN, but think shunting-yard or a variation thereof may be more suitable to SM). If all works well, it'd be fun if the evaluator could be made to work on streams in real-time.

So... who wants to join in?

Things that could be done... - Parse more operators - Create precedence groups for the operators - Decide upon an evaluator model - Formalize a suitable notation for the stack elements - Implement an evaluator (atleast proof-of-concept) - Implement named constants (i.e Pi, samplerate... this is the step that makes it possible to integrate with SM) - Probably a lot more.

Right now, the evaluator is probably the most challenging part.

rl ·

hehe, interesting undertaking. I started something similar some time ago, but decided it wasn't worth the effort when there was a preview release of SM 2 with a complete LUA interpreter integrated (-> He Malc, what's the status on this?)

BTW: shouldn't the stack for 1+2-3 not build like this?: 1 2 + 3 -

mwvdlee ·

rl wrote: BTW: shouldn't the stack for 1+2-3 not build like this?: 1 2 + 3 -

No. The reason is precedence. I placed - on a higher precedence to +, so 1+2-3 is evaluated as 1+(2-3), so 1,2,3,-,+ is the expected order. I mentioned I used the precedence I learned in school, not the one most programming languages use. C, for instance, places precedence of - and + on the same level, which means they should evaluate left-to-right as you described. Perhaps one of the first things to do would be to define the operators and their precedence 😉

FWIW, I don't ever rely on precedence in any language. Parenthesis are so much more readable and reliable than trying to remember the order of all the operators. It gets more difficult if you use multiple different languages, some with subtle differences in precedence.

p.s. It probably isn't the most useful of things to create, but I kinda enjoy building stuff like this and nobody ever needs any other reason with a reason like that 😉. And who knows, with a full evaluator available to the end-user, you might be able to create some wonderfull new synths. Imagine allowing the end-user (not us, but our users) to enter a formula such as "(LFO1 + LFO2) / (LFO3 + 2)". I'm sure somebody can imagine something much more creative and useful.

rl ·

ok, never heard about that. Typically there is a distinction between the binary '-' op and the unary '-' operator which has higher precedence,

Ask a C/java/JS programmer how a+++++b evaluates, you will get a lot different answers 😈

Let's see whether I can contribute a stack machine...

mwvdlee ·

rl wrote: Typically there is a distinction between the binary '-' op and the unary '-' operator which has higher precedence

The OSM does make a distinction between the two; check out the last alternative in the "Term" rule. Although that rule probably is incorrect; as I read it, it should parse "-------4" as valid syntax. Term should probably read "Term ::= ( '-'? '(' Addition ')' ) | REAL " or something, without the silly self-recursion. Or just drop the entire ability to parse stuff like "-(2+3)". Either way, the Java BNF should have a good set of rules dealing with expressions, we could just copy it 😉

rl wrote: Ask a C/java/JS programmer how a+++++b evaluates, you will get a lot different answers 😈

Since you can't do ++ twice (atleast in C, although I think this is only really defined in C++ and perhaps C99), the only way a compiler should succesfully evaluate this is as (a++) + (++b). Many compilers will just throw an error, which I'd prefer in this case, and many will probably try to parse ((a++)++) + b, some might even succeed in parsing it like that. Anyway, it's a nice example of exactly why you should always use parenthesis in math 🙂

Wrote something here? To have a post removed or your name hidden, write to [email protected].

Before your first post

A few rules keep this a friendly place. You agree to them once.

Shown next to what you post, here and in the app. It doesn’t have to be your real name: 3–24 lower-case letters, digits or _ (capitals become lower case, spaces become _).

    Then your post goes up straight away.

    Delete this reply?

    Open it in SynthMaker?

    It goes on the track you’re editing there, in place of that track’s sound, and into My sounds. Your other tracks stay as they are.

    Want to keep that track’s sound? Start a new song in SynthMaker first (Song › New song), then open this.

    Report this reply?

    Only the developer reads reports. The person isn’t told who reported them.

    What’s wrong with it?

    Block this person?

    You won’t see their posts and replies here any more. They aren’t told, and you can unblock them at any time.

    People you’ve blocked

    Their posts and replies are hidden from you. Unblock someone to see them again.

    The community rules

    A few rules keep this a friendly place. Everyone agrees to them once, before their first post.