Denotational semantics is a method for precisely defining programming languages. Most descriptions of programming languages today have a formal syntactic definition (ie using BNF).The semantics, however, is usually described in a natural language, which can be rather imprecise. Denotational sematics allows us to close this gap, and describe the semantics formally.
Because denotational semantics can precisely define programming languages, it is possible in theory to automatically generate a compiler from a language's denotational semantics. However, no one has been able to create a useful automatic compiler generator.
The use of denotational semantics is attributed to Scott and Strachey. However, the general denotational approach can be traced back to Frege (which probably explains why it's so complex ;-).
Robert W. Sebesta, Concepts of Programming Languages, 4th Ed.