Pranay,
I'm going to assume you're trying to use a mostly LL(1) grammar with a RD parser, maybe even using the parser generator supplied by Actipro.
In this case, if you want to do type checking (which is what you're referring to when you say you want a warning for assignments / initializations like ch = 2.3), you'll need some sort of symbol table maintenance so that you know when ch is declared and what it's declared as. If you're doing a .NET language, it could be difficult to do this without a full AST (and even difficult WITH a full AST) since variables don't have to be declared before they are used - at least in a line-number type of "before" concept, that is for fields and members. For locals, obviously they DO need to be declared before use.
Are you writing a parser for C#, C, or some other existing language, or are you making your own new language?
If your language requires declaration before use (in a line-number / token ordering sense), then you can do a single-pass type checking analysis for locals and build your symbol table when you see declarations, and use it to look up the types when parsing expressions.
You can then, in RD, return the "inferred type" from each of your expression productions (expression, term, factor, primary, etc.) that is computed in the manner appropriate for your language (x / y is real, int + real is real, int + int is int, etc.).
It is much less messy, however, to perform type-checking after the syntax analysis phase. In order to do this, though, your AST needs to have all the necessary information in order to compute what you need. This probably means you need to "keep" all the expression stuff in the AST.
Let me know if you need more elaboration on any of this.
Kelly Leahy
Software Architect
Milliman, USA