Could someone please give me some advice/ideas about how to deal with the situations when it's needed to have a look at further declarations to be able to make correct semantic actions on current moment? For example, it is a well-known occurrence when someone writes an interpreter/compiler of some programming language which doesn't support "forward declarations". Let's have an example:
foo(123);//<-- our parser targets here. we estimate we have a function
// invocation, but we have no idea about foo declaration/prototype,
// so we can't be sure that "foo" takes one integer argument.
void foo(int i){
//...
}
It is pretty clear we have to have at least two passes. Firstly we parse all function declarations and get all the needed information such as: the amount arguments the function takes, their types and then we are able to deal with function invocations and resolving the difficulties as above. If we go this way we will must do all these passes using some AST traversing mechanisms/visitors. In this case we have to deal with AST traversing/applying visitors and we must say "good bye" to the all the beauty of phoenix constructions integrated directly in our parsers.
How would you deal with this?