
class Input; // stdin, string, file, istream, socket, ...


class Interpreter {
      SymbolTable* _symtab;
public:
      bool Interpret(Input& inp);  // calls yyparse()
};


Bison can be told to create a reentrant parse by declaring
%pure_parser in the definition section. It will not use global
variables, and yylex() will be called differently.

Interpreter::Interpret(Input&) will call yyparse() on its input. If
this is a string, yyparse() will parse the string and the return. This
means that we can call it again. If it is a file, it will parse the
file's contents. If it is a stdin, a socket or pipe, then yyparse()
will parse until an EOF is encountered.

When a Win is created, then the parser calls Win::Win which will not
return (since we currently have no threaded Xlib and Xt available)
until the X event loop is destroyed. It is, however, possible to call
the interpreter recursively to interpret a string (or other input)
from a Win callback. This would be done as follows:

  void PushButtonCB(..) {

    ::interpreter->Interpret("println \"Hello\";");
    ::interpreter->Interpret("a=23;");
    
  }

The method Interpret() will call yyparse() recursively which is
possible as explained above. Then yyparse() will return and the window
can be further manipulated. The interpreter global instance will keep
state changes since they are reflected in its symbol table. Each
invocation of yyparse() must lookup and modify variables using the
global instance of the interpreter so that state changes are
presistent. This requires the actions in the bison input file
(basic.yacc) to refer to use a different yylval rather than the global
one (which doesn't exist any more).

