It differentiates the tasks based on (get this) what operator you use. When the code is parsed, the parser/compiler finds the operators and decides what to do with the things around it. If + is used for both addition and concatenation, it would depend on the arguments supplied to it. The language decides what to do when it's a mix, for example if, "4" + 5 equals "45" or 9.
Additionally, operators have precedence. That is, certain operators are evaluated sooner than others. Sort of like the order of operations you learn in math. For example, the + and - operators typically have a lower precedence than the * and / (multiplication and division) operators (that is, multiplication operations will happen before addition operations). This is why 4 * 5 + 2
will equal 22 instead of 40. You can find a table of operator precedence here. This is for the C language, but it should be similar for most other languages.
There is also operator associativity. This is (basically) the order which operators of the same type are evaluated. Most of the ones you are used to will be left associative. For example:
4 * 5 * 6 * 7
this is left associative, meaning this:
((4 * 5) * 6) * 7
if there are two or more operators of the same precedence "in a row" (as in the example), then they will be evaluated from left to right. That is, 4 * 5 first, then 20 * 6, then 120 * 7. An example of a right associative operator is the exponent operator:
4 ^ 5 ^ 6 ^ 7
This becomes
4 ^ (5 ^ (6 ^ 7))
These get evaluated from right to left. If the exponent operator were left associative, this would produce the wrong answer.
Think of the associativity as "what side the brackets go on." they're on the left for left associative, and on the right for right associative.
That same link includes the associativity for each operator. Again, it's for the C language, but it should be almost identical for most other languages you will use.