I have a C++ audio project that is a Score-Based Music System for offline computation and audio rendering. It is based on two distinct scores, that actually are text files, one that contains the DAG of the instrument and one with the parametric of that instrument. I implemented two distinct front-end compiler, namely the lexer and the parser to read them distinctly, plus I wrote a Mediator class that acts as linker between them while implementing a semantic analysis. The mechanism is quite simple but ATM works. I also unit tested it even if I am lacking a bit of integration tests. It also contains a back-end part for the audio processing management but actually I do not have any audio processors stable implemented.
Let me provide you also an example to clear the implementation and expectation.
~
// instrument.txt
AudioSystem as;
SinOsc osc;
WriteSF writer;
osc -> writer;
// parameters.txt
double frequency_ = 440;
AudioSystem::as T = 1000;
AudioSystem::as SR = 48000;
SinOsc::osc frequency = frequency_;
WriteSF::writer filename = “testOsc.wav”;
~
Assume that in the Back-End I have an oscillator generator called SinOsc that is registered in a Factory class, that has a parameter called frequency that is a double, and a SoundFiles writer class that has the parameter filename that is the string of the filename to be created. AudioSystem is the container of the processing and contains the time of the total duration, in this case 1 sec, and the sampling rate as variable, both double. Note: in this moment the compiler accepts double or strings as type. 
I have a couple of observations for which I require your feedback.
1. Parameters' score can accept also expression, that are evaluated in the back-end. Expression can be in the following form:
SinOsc::osc frequency = 440*(100 +2); // fixed evaluation
or
SinOsc::osc frequency = 440*(1+t);
with t is a variable (it is not a variable to be rigorous in the sense that is a placeholder which context is extern to the actual scope) that ranges from 0 to 1 in the time of T. Basically, it increments during the evaluation given the request of the Back-End. I would make more clear the declaration and I am considering to introduce a keyword name utime such that there is no need to hard-code t and to make clearer the responsibility of the function to the user. So,
utime t;
SinOsc::osc frequency = 440*(1+t);
Moreover, in this way the user can choose an appropriate name for this function (of time):
utime u;
SinOsc::osc frequency = 440*(1+u);
Here my doubt: The lexer and the parser already taken utime as keyword, however the parser throws an error if a declaration does not contain an assignment, i.e. a variable must be initialized. So I am considering to fit the declaration of utime variable to be compliant with the actual implementation and I have a couple of choices:
a. utime t = 0.;
b. utime t = ();
c. utime t = [AudioSystem](double t){ t = AudioSystem::t; return t; };
The first option should be convenient but it is a "lie", because the value is not used. For example, utime t = 0., or utime t = 0.5; bring to the same results. The second one is a novelty of the syntax, but it underlines clearly the difference between variables and t, that is not a variable in a strict sense. The third approach resembles a lambda function in C++. It sounds interesting because maybe it is the most rigourous from a syntactic point of view, however it introduces several linguistic novelties and maybe too much complexity for a simple implementation.
2. Name collision and resolution. Consider the following example: (Assume in the intruments.txt a declaration like: SinOsc osc1; SinOsc osc2; do not care ATM about connections)
double frequency = 400;
SinOsc::osc1 frequency = 800;
SinOsc::osc2 frequency = frequency;
What is the expected behavior in this case?
I can not allow that each variable has a different name because SinOsc has a variable called "frequency", so if you have more than one SinOsc there are no alternatives. A proposal can be that then ambiguity is present, like in this case, it is responsibility of the user to resolve it, otherwise the semantic analyzer will throw an error. Possible resolution:
SinOsc::osc2 frequency = double::frequency;
or
SinOsc::osc2 frequency = SinOsc::osc1::frequency;
Pros: the name collision is solved. Moreover, this solution allows to rigorously assign values from variables that belongs to audio processors, like in this case the usage of SinOsc::osc1::frequency .
Cons: Type are "elevated" to namespace (I do not know if it is a real issue or cons, but I am listing it). The syntax can be long, like SinOsc::osc1::frequency.