Note:
Interactive mode Bison is still an experimental system and is work in progress. If you want to contribute code, please send a patch to me.
New - Browse the sources at Google Project hosting
Click here to download the source tar ball. To compile sources perform the usual dance:$ tar -xvjf iBison.tar.bz2 $ cd iBison/ $ ./configure $ make $ sudo make installIt is up to you to install it or not. Its just the usual Bison 2.3 installation except that you get an extra command line option (-i) for interactive mode parsing. Interactive mode Bison can also be used by executing the generated binary from the src/ directory.
$ bison -i parser.y Welcome to Bison 2.3 interactive mode. (interactive)_This will present you with a prompt where you can enter commands. A simple < Enter > keystroke will repeat the last command. The following commands are currently available:
test < inputfile > - Start running a parse on the input file.
next - Single step through a parse.
rule < ruleno > - Display a rule.
state < stateno > - Display rules in a state along with position of the dot.
token < token_string > - Supply a token to the parser.
stack - Display the state and token stacks.
break < token-string > - break at first occurrence of token-string from this point.
lexer <lexer module> - Load a lexical analyzer dynamically.
(1) Load a lexical analyzer dynamically - If you have a flex specification for your grammar, you must compile the output of flex with gcc -shared switch to produce a shared object file. Your flex specification should NOT contain a main () function.
$ flex lexer.l $ gcc -c lex.yy.c $ gcc -shared -o lex.so lex.yy.oNow you are ready to load lex.so inside bison interactive mode. Make sure that your environment variable LD_LIBRARY_PATH includes the directory in which lexer.so is present. Otherwise it is not possible to load the lexer. The 'lexer' command loads a dynamic lexer module:
(interactive) lexer lex.so
(2) In case you don't have a flex specification, you can supply tokens manually by using the token command. You must supply the string used in %token declaration inside the grammar file. For example if you have declared:
%token TOK_INTthen you have to use token command like this:
(interactive) token TOK_INTThis command can also be used to override the tokens supplied by a dynamically loaded lexer. The most recent token will always be used for the next parse step. The interactive parser breaks at every one of the following steps unless a break point is set:
1. A token is required by the parser.
2. A token is read from the (dynamically loaded) lexical analyzer.
3. The parser performed a SHIFT operation.
4. The parser performed a REDUCE operation.
%{
# include "calcparser.tab.h"
# undef yywrap
# define yywrap() 1
%}
%option noyywrap
int [0-9]+
blank [ \t]
%%
{blank}+
[\n]+
\+ return OPERATOR_PLUS;
- return OPERATOR_MINUS;
\* return OPERATOR_MULT;
\/ return OPERATOR_DIV;
\( return LPAREN;
\) return RPAREN;
{int} return NUMBER;
. {fprintf(stderr,"Invalid token!\n");}
%%
Note that I have included calcparser.tab.h which I plan to generate using bison -d option. Download this file.
%{
/* A simple calculator */
void yyerror(const char *s);
%}
%token NUMBER
%token OPERATOR_PLUS
%token OPERATOR_MINUS
%token OPERATOR_MULT
%token OPERATOR_DIV
%token LPAREN
%token RPAREN
%left OPERATOR_PLUS OPERATOR_MINUS
%left OPERATOR_MULT OPERATOR_DIV
%%
exp: exp OPERATOR_PLUS exp
| exp OPERATOR_MINUS exp
| exp OPERATOR_MULT exp
| exp OPERATOR_DIV exp
| LPAREN exp RPAREN
| NUMBER
;
%%
void
yyerror(cosnt char *s)
{
fprintf(stderr,"Syntax error: %s\n",s);
}
Download this file.
$ bison -d calcparser.y $ flex calclexer.l $ gcc -c lex.yy.c $ gcc -shared -o calclexer.so lex.yy.o $ export LD_LIBRARY_PATH="."
$ cat >calcinput (8+6)*9 ^dNow you can start bison with the -i switch like this:
$bison -i calcparser.y Welcome to Bison 2.3 interactive mode. Type "help" for assistance. Please report bugs to spopur2@uic.edu. (interactive) lexer calclexer.so Lexer loaded successfully. (interactive) test calcinput Opening file...ready to test. (interactive) next Reading a token...next token is: ( (LPAREN) (interactive) Token is shifted. Entering state 2 Stacks:(states, tokens) 0 2 ( (interactive) Reading a token...next token is: 8 (NUMBER) (interactive) Token is shifted. Entering state 1 Stacks:(states, tokens) 0 2 1 ( 8 (interactive) Popping stack: 8 Reduced by rule #6 exp: NUMBER Stacks:(states, tokens) 0 2 4 ( exp (interactive) Reading a token...next token is: + (OPERATOR_PLUS) (interactive) Token is shifted. Entering state 6 Stacks:(states, tokens) 0 2 4 6 ( exp + (interactive) Reading a token...next token is: 6 (NUMBER) (interactive) Token is shifted. Entering state 1 Stacks:(states, tokens) 0 2 4 6 1 ( exp + 6 (interactive) Popping stack: 6 Reduced by rule #6 exp: NUMBER Stacks:(states, tokens) 0 2 4 6 11 ( exp + exp (interactive) Reading a token...next token is: ) (RPAREN) (interactive) Popping stack: exp + exp Reduced by rule #1 exp: exp OPERATOR_PLUS exp Stacks:(states, tokens) 0 2 4 ( exp (interactive) Token is shifted. Entering state 10 Stacks:(states, tokens) 0 2 4 10 ( exp ) (interactive) Popping stack: ) exp ( Reduced by rule #5 exp: LPAREN exp RPAREN Stacks:(states, tokens) 0 3 exp (interactive) Reading a token...next token is: * (OPERATOR_MULT) (interactive) Token is shifted. Entering state 8 Stacks:(states, tokens) 0 3 8 exp * (interactive) Reading a token...next token is: 9 (NUMBER) (interactive) Token is shifted. Entering state 1 Stacks:(states, tokens) 0 3 8 1 exp * 9 (interactive) Popping stack: 9 Reduced by rule #6 exp: NUMBER Stacks:(states, tokens) 0 3 8 13 exp * exp (interactive) Popping stack: exp * exp Reduced by rule #3 exp: exp OPERATOR_MULT exp Stacks:(states, tokens) 0 3 exp (interactive) Reading a token...next token is: <Note that once your enter the 'next' command, you just need to press the <Enter> key to repeat the command. Also, you can observe the states with the 'state' command whenever you want during the execution of the test parse.> ($end) (interactive) String is accepted. $_