Sign in to follow this  
ShmeeBegek

More bison issues (shift/reduce,reduce/reduce)

Recommended Posts

I am having more issues with Bison, however this time I don't think that it's a syntax problem like before, I've spent several hours trying to figure it out but without much like (I can't switch to ANTLR because I'm using C). Here is the grammar so far:

%{

#include "util/util.h"
#include "precompiler/keywords.h"
#include "precompiler/precomp.h"
#include "ob/ob.h"

extern char *opcltext;
oc_vardecl_t *vardecl_tp;
oc_expression_t *expr_tp;

void opclerror(char *s)
{
	EW_Report(ew_error,"(at %s) %s",opcltext,s);
}


#define COMPY_UNARY(__type,__op,__ret) expr_tp=OBM_Expression();									expr_tp->type=(__type);													expr_tp->ops[0]=(__op);													OBW_Construct((ocon_t*)(expr_tp));										(__ret)=OBW_LastIndex();


#define COMPY_BINARY(__type,__lop,__rop,__ret) 									expr_tp=OBM_Expression();													expr_tp->type=(__type);														expr_tp->ops[0]=(__lop);													expr_tp->ops[1]=(__rop);													OBW_Construct((ocon_t*)(expr_tp));											(__ret)=OBW_LastIndex();

#define COMPY_TRIARY(__type,__lop,__mop,__rop,__ret)								 	expr_tp=OBM_Expression();													expr_tp->type=(__type);														expr_tp->ops[0]=(__lop);													expr_tp->ops[1]=(__mop);													expr_tp->ops[2]=(__rop);													OBW_Construct((ocon_t*)(expr_tp));											(__ret)=OBW_LastIndex();

%}

%union
{
	char 		*string;
	char		 ident[256];
	long long 	 integer;	// NOTE: Not long enough
	double		 dbl;
	float		 flt;
	char		 chr;
	
	ob_bid		 index;	
	
	onamelist	 namelist;
	obidlist	 indexlist;
	
	ob_tid		 tiny;
	otidlist	 tinylist;
	
	ocon_t		*pcon;
	
	oc_file_t	*pfile;
	oc_import_t	*pimport;
	oc_module_t	*pmodule;
	oc_typename_t	*ptypename;
	oc_varsingle_t 	*pvar_single;
	oc_expression_t *pexpr;
}

/* Keyword tokens must be first */
%token 	tok_key_cdecl,
		tok_key_extern,
		tok_key_module,
		tok_key_import,
		tok_key_mapto,
		tok_key_static,
		tok_key_typedef,
		tok_key_align,
		tok_key_this,
		tok_key_pure,
		tok_key_virtual,
		tok_key_const,
		tok_key_typeof,
		tok_key_returnof,
		tok_key_sizeof,
		tok_key_stacksizeof,
		tok_key_dimof,
		tok_key_uniform,
		tok_key_atomic,
		tok_key_volatile,
		tok_key_register,
		tok_key_return,
		tok_key_if,
		tok_key_else,
		tok_key_switch,
		tok_key_case,
		tok_key_default,
		tok_key_do,
		tok_key_while,
		tok_key_for,
		tok_key_continue,
		tok_key_break,
		tok_key_throw,
		tok_key_try,
		tok_key_catch,
		tok_key_operator,
		tok_key_explicit,
		tok_key_template,
		tok_key_initially,
		tok_key_finally,
		tok_key_invisible,
		tok_key_visible,
		tok_key_true,
		tok_key_false,
		tok_key_huge,
		tok_key_big,
		tok_key_nat,
		tok_key_small,
		tok_key_tiny,
		tok_key_longer,
		tok_key_long,
		tok_key_int,
		tok_key_short,
		tok_key_shorter,
		tok_key_byte,
		tok_key_float,
		tok_key_double,
		tok_key_void,
		tok_key_bool,
		tok_key_uhuge,
		tok_key_ubig,
		tok_key_unat,
		tok_key_usmall,
		tok_key_utiny,
		tok_key_ulonger,
		tok_key_ulong,
		tok_key_uint,
		tok_key_ushort,
		tok_key_ushorter,
		tok_key_ubyte,
		tok_key_struct,
		tok_key_union,
		tok_key_claim,
		tok_key_reclaim,
		tok_key_as,
		tok_key_free,
		tok_key_enum

/* Special tokens */
%token tok_sp_inc tok_sp_dec tok_sp_shl tok_sp_shr tok_sp_point 
%token tok_sp_grteqt tok_sp_leseqt tok_sp_eqt tok_sp_noteqt
%token tok_sp_logand tok_sp_logor
%token tok_sp_assadd tok_sp_asssub tok_sp_assmul tok_sp_assdiv tok_sp_assmod tok_sp_assshl tok_sp_assshr 
%token tok_sp_assand tok_sp_assxor tok_sp_assbor tok_sp_asslogand tok_sp_asslogor

/* Precidence */
%left tok_sp_point '.'
%left '*' '/' '%'
%left '+' '-'
%left tok_sp_shl tok_sp_shr
%left '>' '<' tok_sp_grteqt tok_sp_leseqt
%left tok_sp_eqt tok_sp_noteqt
%left '&'
%left '^'
%left '|'
%left tok_sp_logand
%left tok_sp_logor
// TODO: [right-assoc] Turnary??
%right tok_sp_assadd tok_sp_asssub tok_sp_assmul tok_sp_assdiv tok_sp_assmod tok_sp_assshl tok_sp_assshr tok_sp_assand tok_sp_assxor tok_sp_assbor tok_sp_asslogand tok_sp_asslogor
%left ','
%nonassoc	UPLUS UNEGATE UDEREF UREF UNOT ULOGNOT UPREINC UPOSTINC UPREDEC UPOSTDEC


/* Now tokens */
%token <ident> 		tok_ident
%token <integer> 	tok_integer
%token <dbl>		tok_dbl
%token <dbl>		tok_flt

%token <string>		tok_nc_string
%token <string>		tok_nu_string
%token <string>		tok_pc_string
%token <string>		tok_pu_string

%token <chr>		tok_character


/*	Symbols */

%type <pfile>		ofile
%type <index>		top_level

%type <index>		import_stmt	
%type <pimport>		import_common

%type <index>		module_decl
%type <pmodule>		module_proto
%type <pmodule>		module_qual_proto
%type <index>		module_nest
%type <indexlist>	module_nest_list

%type <index>		var_decl
%type <index>		var_decl_single
%type <pvar_single>	var_decl_single_ptr
%type <indexlist>	var_decl_list

%type <indexlist>	array_bounds
%type <index>		array_bound

%type <index>		expression

%type <index>		typename
%type <indexlist>	typename_list
%type <ptypename>	typename_ptr
%type <ptypename>	typename_ptr_base
%type <tiny>		primitive_type

%type <tinylist>	indirection_list
%type <tiny>		level_of_indirection

%type <index>		constant_expr
%type <pexpr>		basic_constant

%type <namelist>	name_list
%type <namelist>	com_sep_namelist



%%

	/* Top of the tree */
	
treetop:	ofile										{OBW_Construct((ocon_t*)($1));}
		| {}
		;

	/* Entire file construct */
	
ofile:		top_level									{$$=OBM_File();OBC_DONEST($$,$1);}
		|   ofile top_level								{$$=$1;OBC_DONEST($$,$2);}
		;

	/*	Top-level construct */
	
top_level:	import_stmt									{$$=$1;}
		|	module_decl									{$$=$1;}
		;

	/* import */

	
import_stmt:	import_common ';'							{$1->type=oc_import_simple;OBW_Construct((ocon_t*)($1));$$=OBW_LastIndex();}
		|		import_common tok_key_as tok_ident ';'		{$1->type=oc_import_as;$1->str=$3;OBW_Construct((ocon_t*)($1));$$=OBW_LastIndex();}
		|		import_common tok_key_mapto tok_ident ';'	{$1->type=oc_import_mapto;$1->str=$3;OBW_Construct((ocon_t*)($1));$$=OBW_LastIndex();}
		;

import_common:	tok_key_import name_list					{$$=OBM_Import();$$->modbase=$2;}
		;


	/* module */

module_decl:		module_qual_proto	'{' module_nest_list '}'	{$1->head.nest=$3;OBW_Construct((ocon_t*)($1));$$=OBW_LastIndex();}
		|			module_qual_proto	'{'  '}'	{OBW_Construct((ocon_t*)($1));$$=OBW_LastIndex();}
		;

module_qual_proto:	module_proto					{$$=$1;}
		|			tok_key_extern module_proto			{$$=$2;$$->flags|=ocmf_extern;}
		;

module_proto:	tok_key_module name_list						{$$=OBM_Module();$$->name = $2;}
		|		tok_key_module name_list ':' com_sep_namelist	{$$=OBM_Module();$$->name = $2;$$->nested = $4;}
		;
		
module_nest_list:	module_nest					{$$=OBM_BIDList();OB_AddBID($$,$1);}
			|	module_nest_list module_nest	{$$=$1;OB_AddBID($$,$2);}
			;

module_nest:	var_decl						{$$=$1;}
		;

	/* variable declarations */

var_decl:		typename var_decl_list ';'		{
													vardecl_tp=OBM_VarDecl();
													
													vardecl_tp->type = $1;
													vardecl_tp->head.nest = $2;
													
													OBW_Construct((ocon_t*)(vardecl_tp));
													$$=OBW_LastIndex();
												}
	;

var_decl_list:	var_decl_single								{$$=OBM_BIDList();OB_AddBID($$,$1);}
	|			var_decl_list ',' var_decl_single			{$$=$1;OB_AddBID($$,$3);}
	;

var_decl_single:		var_decl_single_ptr			{OBW_Construct((ocon_t*)($1));$$=OBW_LastIndex();}
	;

var_decl_single_ptr:	tok_ident array_bounds '=' expression	{
																	$$=OBM_VarSingle();
																	$$->name = OB_CloneStr($1);
																	$$->initial = $4;
																	$$->dims=$2;
																}
	|					tok_ident array_bounds					{
																	$$=OBM_VarSingle();
																	$$->name = OB_CloneStr($1);
																	$$->initial=BID_INVALID;
																	$$->dims=$2;
																	
																}
	|					tok_ident '=' expression				{
																	$$=OBM_VarSingle();
																	$$->name = OB_CloneStr($1);
																	$$->initial = $3;
																}
	|					tok_ident								{
																	$$=OBM_VarSingle();
																	$$->name = OB_CloneStr($1);
																	$$->initial=BID_INVALID;
																}
	;

array_bounds:	array_bound									{$$=OBM_BIDList();OB_AddBID($$,$1);}
	|			array_bounds array_bound					{$$=$1;OB_AddBID($$,$2);}
	;

array_bound:	'[' expression ']'							{$$=$2;}
	;

	/* Types */
	
typename_list:	typename									{$$=OBM_BIDList();OB_AddBID($$,$1);}
		|		typename_list ',' typename					{$$=$1;OB_AddBID($$,$3);}
		;

typename:		typename_ptr	{OBW_Construct((ocon_t*)($1));$$=OBW_LastIndex();}
		;
		
typename_ptr:	typename_ptr_base						{$$=$1;}
|				typename_ptr_base indirection_list		{$$=$1;$$->levels = $2;}
		;

 /* TODO: This should handle tok_sp_shr and tok_sp_shl! */
typename_ptr_base:	
		primitive_type												{
																		$$=OBM_TypeName();
																		$$->flags|=octf_primitive;
																		$$->ts.prim	= $1;
																	}
		|		name_list '<' typename_list '>'						{
																		$$=OBM_TypeName();
																		$$->ts.base		= $1;
																		$$->tempargs	= $3;
																	}
		|		name_list											{
																		$$=OBM_TypeName();
																		$$->ts.base	= $1;
																	}
																	
		/* Malformed input */
		|		primitive_type '<' typename_list '>'	{opclerror("Primitive types may not have template arguments");$$=OBM_TypeName();}
		;
	

primitive_type:	tok_key_huge		{$$=ob_prim_huge;}
			|	tok_key_big			{$$=ob_prim_big;}
			|	tok_key_nat			{$$=ob_prim_nat;}
			|	tok_key_small		{$$=ob_prim_small;}
			|	tok_key_tiny		{$$=ob_prim_tiny;}
			|	tok_key_longer		{$$=ob_prim_longer;}
			|	tok_key_long		{$$=ob_prim_long;}
			|	tok_key_int			{$$=ob_prim_int;}
			|	tok_key_short		{$$=ob_prim_short;}
			|	tok_key_shorter		{$$=ob_prim_shorter;}
			|	tok_key_byte		{$$=ob_prim_byte;}
			|	tok_key_float		{$$=ob_prim_float;}
			|	tok_key_double		{$$=ob_prim_double;}
			|	tok_key_void		{$$=ob_prim_void;}
			|	tok_key_bool		{$$=ob_prim_bool;}
			|	tok_key_uhuge		{$$=ob_prim_uhuge;}
			|	tok_key_ubig		{$$=ob_prim_ubig;}
			|	tok_key_unat		{$$=ob_prim_unat;}
			|	tok_key_usmall		{$$=ob_prim_usmall;}
			|	tok_key_utiny		{$$=ob_prim_utiny;}
			|	tok_key_ulonger		{$$=ob_prim_ulonger;}
			|	tok_key_ulong		{$$=ob_prim_ulong;}
			|	tok_key_uint		{$$=ob_prim_uint;}
			|	tok_key_ushort		{$$=ob_prim_ushort;}
			|	tok_key_ushorter	{$$=ob_prim_ushorter;}
			|	tok_key_ubyte		{$$=ob_prim_ubyte;}
			;

indirection_list:	level_of_indirection						{$$=OBM_TIDList();OB_AddTID($$,$1);}
		|			tok_sp_inc									{$$=OBM_TIDList();OB_AddTID($$,obl_rn);OB_AddTID($$,obl_rn);}
		|			tok_sp_dec									{$$=OBM_TIDList();OB_AddTID($$,obl_wn);OB_AddTID($$,obl_wn);}
		|			indirection_list level_of_indirection		{$$=$1;OB_AddTID($$,$2);}
		;

// TODO: Somehow this generates reduce/reduce conflicts with expression...
level_of_indirection:	'*'			{$$=obl_rwn;}
					|	'+'			{$$=obl_rn;}
					|	'-'			{$$=obl_wn;}
					|	'@'			{$$=obl_rwv;}
					|	'&'			{$$=obl_rv;}
					|	'%'			{$$=obl_wv;} 
					;

	/* expressions (TODO function call) */
expression:		constant_expr		{$$=$1;}
	|		'(' expression ')'		{$$=$2;}
	|			tok_ident		{
									expr_tp=OBM_Expression();
									expr_tp->type=ocet_variable;
									expr_tp->ts.variable=OB_CloneStr($1);
									OBW_Construct((ocon_t*)(expr_tp));
									$$=OBW_LastIndex();
								}

	/* Binary */
	|	expression '+' expression		{COMPY_BINARY(ocet_add,	$1,$3,$$);}
	|	expression '-' expression		{COMPY_BINARY(ocet_sub,	$1,$3,$$);}
	|	expression '*' expression		{COMPY_BINARY(ocet_mul,	$1,$3,$$);}
	|	expression '/' expression		{COMPY_BINARY(ocet_div,	$1,$3,$$);}
	|	expression '%' expression		{COMPY_BINARY(ocet_mod,	$1,$3,$$);}

	/* Unary */
	|	'+' expression	%prec UPLUS         	{COMPY_UNARY(ocet_plus		,$2,$$);}
	|	'-' expression	%prec UNEGATE			{COMPY_UNARY(ocet_negate	,$2,$$);}
	|	'*' expression	%prec UDEREF			{COMPY_UNARY(ocet_deref		,$2,$$);}
	|	'&' expression	%prec UREF				{COMPY_UNARY(ocet_ref		,$2,$$);}
	|	'~' expression	%prec UNOT				{COMPY_UNARY(ocet_not		,$2,$$);}
	|	'!' expression	%prec ULOGNOT			{COMPY_UNARY(ocet_lognot	,$2,$$);}
	|	tok_sp_inc expression	%prec UPREINC	{COMPY_UNARY(ocet_preinc	,$2,$$);}
	|	tok_sp_dec expression	%prec UPREDEC	{COMPY_UNARY(ocet_predec	,$2,$$);}
	|	expression tok_sp_inc 	%prec UPOSTINC	{COMPY_UNARY(ocet_postinc	,$1,$$);}
	|	expression tok_sp_inc 	%prec UPOSTDEC	{COMPY_UNARY(ocet_postdec	,$1,$$);}


	;

/*
	ocet_add,				// +
	ocet_sub,				// -
	ocet_mul,				// *
	ocet_div,				// /
	ocet_mod,				// %
	ocet_grt,				// >
	ocet_les,				// <
	ocet_grteqt,			// >=
	ocet_leseqt,			// <=
	ocet_eqt,				// ==
	ocet_noteqt,			// !=
	ocet_logand,			// &&
	ocet_logor,				// ||
	ocet_ass,				// =
	ocet_shr,				// >>
	ocet_shl,				// <<
	ocet_and,				// &
	ocet_bor,				// |
	ocet_xor,				// ^
	ocet_com,				// ,

	ocet_assadd,			// +
	ocet_asssub,			// -
	ocet_assmul,			// *
	ocet_assdiv,			// /
	ocet_assmod,			// %
	ocet_assshr,			// >>=
	ocet_assshl,			// <<=
	ocet_assand,			// &=
	ocet_assbor,			// |=
	ocet_assxor,			// ^=
	
	ocet_dot,				// .
	ocet_arrow,				// ->

	ocet_array,				// []
*/

constant_expr:	basic_constant					{OBW_Construct((ocon_t*)($1));$$=OBW_LastIndex();}
	|			typename ':' basic_constant		{$3->type|=ocef_prefixtype;$3->prefixtype=$1;OBW_Construct((ocon_t*)($3));$$=OBW_LastIndex();}
	;

basic_constant:		tok_key_true				{$$=OBM_Expression();$$->type=ocet_boolconst;$$->ts.boolconst=1;}
	|				tok_key_false				{$$=OBM_Expression();$$->type=ocet_boolconst;$$->ts.boolconst=0;}
	|				tok_integer					{$$=OBM_Expression();OB_IntConst($$,$1);}
	|				tok_flt						{$$=OBM_Expression();$$->type=ocet_floatconst;$$->ts.floatconst=$1;}
	|				tok_dbl						{$$=OBM_Expression();$$->type=ocet_doubleconst;$$->ts.doubleconst=$1;}
	|				tok_nc_string				{$$=OBM_Expression();$$->type=ocet_stringconst;$$->ts.stringconst.flags=ocscf_nullterm;$$->ts.stringconst.str=OB_CloneStr($1);}
	|				tok_nu_string				{$$=OBM_Expression();$$->type=ocet_stringconst;$$->ts.stringconst.flags=ocscf_nullterm|ocscf_wide;$$->ts.stringconst.str=OB_CloneStr($1);}
	|				tok_pc_string				{$$=OBM_Expression();$$->type=ocet_stringconst;$$->ts.stringconst.flags=0;$$->ts.stringconst.str=OB_CloneStr($1);}
	|				tok_pu_string				{$$=OBM_Expression();$$->type=ocet_stringconst;$$->ts.stringconst.flags=ocscf_wide;$$->ts.stringconst.str=OB_CloneStr($1);}
	;
	
	/* General Stuff */
	
name_list:		tok_ident							{$$=OBM_NameList();OB_AddName($$,$1);}
		|		name_list '.' tok_ident				{$$=$1;OB_AddName($$,$3);}
		;


com_sep_namelist:	tok_ident						{$$=OBM_NameList();OB_AddName($$,$1);}
		|		com_sep_namelist ',' tok_ident		{$$=$1;OB_AddName($$,$3);}
		;


%%

void PREC_Compile(umf_ptr_t *in)
{
	opcl_fp=in;
	
	opclparse();
}

The problem that I'm having is two-fold, and I think that I've narrowed it down: 1. Somehow the binary operators in 'expression' are conflicting with the usage of the same symbols in 'level_of_indirection', producing reduce/reduce conflicts. 2. It has been a while since I messed with precedence in bison/yacc, and I think that I must have done something wrong with the ++ (tok_sp_inc) and -- (tok_sp_dec) operators in 'expression' because they are giving me shift/reduce conflicts. My problem is probably obvious, Thanks, ~SPH

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this