Closed bet20ICL closed 2 years ago
The first solution would be correct, however, the second one not quite. Maybe if you have a look at the type of FUNCTION_NAME
that will give a hint as to why. However, you also don't need to write everything as one statement, you can use multiple statements inside the curly braces.
FUNCTION_NAME
doesn't show up in the first solution though, what is the point of defining FUNCTION_NAME
if it's not used?
Well yeah, that's just a personal choice. You can choose not to use it, or use it and write conditional code inside of your FACTOR rule instead (similar to your second solution). The latter does create a bit of an easier to read grammar, as well as nicer code if you wrap the conditional code in a function.
Ahh ok thanks. Is there definitely no way of encapsulating everything into a line similar to this,
FACTOR : FUNCTION_NAME T_LBRACKET EXPR T_RBRACKET { $$ = new Function($3); }
if we can somehow tell new Function
to create a specific object based on FUNCTION_NAME
? That seems like the most natural reason why FUNCTION_NAME
would even exist.
Yeah that would be more natural, but eventually you will still have to split on the string right? Then I argue it's better to do the if-statement once during the parsing (by using parse rules or actual if-statements) rather than creating a Function
class that takes in a string, but then always has to compare the string internally to do the right operation.
Ok that makes sense, thanks!
I am having trouble understanding the role of the 'FUNCTION_NAME' non-terminal.
I feel that the existence of
FUNCTION_NAME
suggests that something like this is possible:FACTOR : FUNCTION_NAME T_LBRACKET EXPR T_RBRACKET { $$ = new Function($3); }
But this doesn't work because
Function
is an abstract class andFUNCTION_NAME
isn't being used in the action. Is there a way of programmatically instantiating objects that derive from the same base class in C++?All other solutions that I can think of seem inelegant, because they nullify the need for
FUNCTION_NAME
.FACTOR : T_LOG T_LBRACKET EXPR T_RBRACKET { $$ = new LogFuction($3); } | etc.
FACTOR : FUNCTION_NAME T_LBRACKET EXPR T_RBRACKET { FUNCTION_NAME == T_LOG ? $$ = new LogFunction($3) : etc.; }
`