Given an expression, we must determine its type. Expressions are formatted as follows:
- <expression> ::= <constant> | <function>(<args>)
- <args> ::= <expression> | <expression>,<args>
- <constant> ::= <identifier>
- <function> ::= <identifier>
- <identifier> ::= between 1 and 10 letters ('a'-'z', 'A'-'Z'), inclusive
Some examples of valid expressions are "x", "upper(x)", "ord(upper(x))", "succ(succ)", "fst(x,x)".
To aid us in determining the type of an expression, we are given a list of type definitions. Each element of the String[] definitions is formatted as follows:
- <definition> ::= <type_expression>:<type_name>
- <type_expression> ::= <constant> | <function>(<type_args>)
- <type_args> ::= <type_name> | <type_name>,<type_args>
- <type_name> ::= <identifier>
For example:
- "x:Char" means that the constant "x" has type "Char".
- "succ(Int):Int" means that the function named "succ" that takes a parameter of type "Int" has type "Int".
- "upper(Char):Char" means that the function named "upper" that takes a parameter of type "Char" has type "Char".
- "ord(Char):Int" means that the function named "ord" that takes a parameter of type "Char" has type "Int".
- "fst(Int,Int):Int" means that the function named "fst" that takes two parameters, both of type "Int", has type "Int".
In general, "<constant>:<type_name>" means that the constant named <constant> will have type <type_name>, and "<function>(<type_args>):<type_name>" means that the function named <function> will have type <type_name> if and only if its argument types match <type_args> exactly (the same number of arguments, with the types in the exact order given).
Using these example definitions, we can determine the types of three of the example expressions given above. "x" has type "Char", "upper(x)" has type "Char", and "ord(upper(x))" has type "Int". We cannot determine the type of "succ(succ)" because all we know is that a function named "succ" has type "Int" if its argument is of type "Int". In this case, we cannot determine the type of its argument. We cannot determine the type of "fst(x,x)" because all we know is that "fst" is of type "Int" if its two arguments are of type "Int". In this case, both arguments are of type "Char".
Given a String expression and a String[] definitions, return the type of expression. If the type cannot be determined using the given definitions, return an empty String ("").
|