'lvalue' means left value. It's … got a bit of a history, going mack to when the C language was invented back in the '70s. Basically, it means "something you can put on the left-hand side of an assignment operator".
Consider x = 5+3;
the subexpressions 'x' and '5+3' are both of type int (presumably) and both of them have some sort of integer value. but '5+3' is not an lvalue, so
5 + 3 = x;
Will give you the error. In terms of types of expressions, it's syntactically and semantically (up to a point) ok. But you can't generate code for it - the constant expression '5+3' doesn't resolve down to a memory location where the value of x can be put. The compiler can parse it, can understand the subexpressions that make up the expression. The failure happens way down near the end of the line, working out what the side-effect of that '=' should be, which is very nearly the last thing that the compiler needs to do.
Other languages (eg: Pascal) use syntax - the left hand side of an assignment must be a variable or an array reference. But in C, the left hand side can be something like a reference to an element of an array returned by a function specified by some other function:
extern int *foo(char *, int, int);
extern int bar(int);
foo("test", 1, 2)[bar(4)-3] = 5+3;
So limiting the syntax doesn't work. It's too complicated. Instead, C introduced the idea that in addition to an expression having a type and a value, an expression may or may not be an lvalue.