
package PbyaccTest ;

# Nadim Khemir

use strict ;
use warnings ;

# Extend current package with a parser and a lexer

my $yylval = 111 ; # C code doesn't need to check if this variable exists

#use Inline Pbyacc => Config => PBYACC_GENERATE_H_FILE => 1 ;
use Inline Pbyacc =><<'PBYACC' ;
%token INTEGER FLOAT IDENT

%left	'+' '-'
%left	'*' '/'

%start	stmt_list

%%

stmt_list:	/* empty */
	|	stmt_list stmt
	;

stmt:	expr terminator
		{ print $1, $P = $1; }
	;

terminator:	'\n' { $$ = $1; } ;

expr:	'(' expr ')'
		{ $$ = $2; }
	| expr '+' expr
		{ $$ = $1 + $3; }
	| expr '-' expr
		{ $$ = $1 - $3; }
	| expr '*' expr
		{ $$ = $1 * $3; }
	| INTEGER
		{ $$ = $1; }
	| FLOAT
		{ $$ = $1; }
	;

%%

PBYACC

use Inline Flex => Config => FLEX_COMMAND_LINE => 'flex -L -f -8 -oOUTPUT_FILE INPUT_FILE' ;
use Inline Flex =><<'END_FLEX' ;
%option noyywrap
%option prefix="Default"

%{
#define INTEGER  257
#define FLOAT    258
#define IDENT    259
%}

%{
// replacement macro
%}
exp		(([eE][0-9]+)?)
fltsuf   (([lL]|[fF])?)
intsuf   (([lL]?[uU]?)|([uU]?[lL]?))

%%

[0-9]+[eE][0-9]+{fltsuf} |
[0-9]*\.[0-9]+{exp}{fltsuf} |
[0-9]+\.[0-9]*{exp}{fltsuf} {
	SV * perl_yylval = get_sv("PbyaccTest::yylval", FALSE) ;
	printf("%p\n", perl_yylval) ;
	sv_setnv(perl_yylval, atof(yytext)) ;
	return(FLOAT) ;
	}
	
[1-9][0-9]*{intsuf} {
	SV * perl_yylval = get_sv("PbyaccTest::yylval", FALSE) ;
	printf("%p\n", perl_yylval) ;
	sv_setiv(perl_yylval, atoi(yytext)) ;
	return(INTEGER) ;
	}

[a-z_A-Z][a-z_A-Z0-9]+ { return(IDENT) ; } 
[A-Za-z_] { return(IDENT) ; /* single_character */}

[\t ]+ ; // ignore

\n { return('\n') ;}

%{
%}

%%
END_FLEX

#-------------------------------------------------------------------------------
# test 1
#-------------------------------------------------------------------------------
yylex() ;

print __PACKAGE__, "\n" ;
print "$PbyaccTest::yylval\n" ;
print "$yylval\n" ;

#-------------------------------------------------------------------------------
# test 2
#-------------------------------------------------------------------------------
sub PrintError {print @_, "\n"} ;
sub PrintDebug {print @_, "\n"} ;

my $parser = new PbyaccTest(\&yylex, \&PrintError, \&PrintDebug) ;

while(1)
{
	# yyparse calls yylex stub
	$parser->yyparse() ;
}

1 ;

