The Unix Heritage Society mailing list
 help / color / mirror / Atom feed
From: Lars Brinkhoff <lars@nocrew.org>
To: tuhs@tuhs.org
Subject: [TUHS] Archaic yacc C grammar
Date: Sun, 28 Oct 2018 21:34:49 +0000	[thread overview]
Message-ID: <7wsh0piwli.fsf@junk.nocrew.org> (raw)

Hello,

This is Alan Snyder's C grammar.  It's supposedly for yacc, but it's
probably using some really ancient version.  Maybe from when Alan did a
stint at Bell labs and converted yacc from B to C.

Does anyone recognize this type of yacc input?  I don't have the
corresponding yacc version, and the one in V6 isn't happy about this
file.  What would it take to update the grammar for V6 yacc?  Add in
some %term, replace \\ with %%?



	#     C GRAMMAR     #
	#    28 May 1978    #
	#    Alan Snyder    #


#	26 acceptable conflicts:

	2 S/R conflicts for (parsing) ambiguity between
		declarators and function_declarators
	1 S/R conflict for the C ELSE ambiguity
	4 R/R conflicts for the (parsing) problem with regard
		to integer constants as initial_values
	12 R/R conflicts for the (parsing) problem with regard
		to identifiers in function calls
	1 R/R conflict for the (parsing) problem with regard
		to identifiers in goto statements
	4 R/R conflicts and 1 S/R conflict for TYPEDEFs
	1 S/R conflict for ambiguous cast types
		(int ()) = (int x()) not (int (x))

	Approximate description:

 18	S/R	(	shift 37	reduce 141
 50	S/R	(	shift 37	reduce 71
 81	S/R	(	shift 37	reduce 71
113	R/R	(	reduce 141	reduce 140
113	R/R	(	reduce 159	reduce 140
113	R/R	*	reduce 159	reduce 141
113	S/R	:	shift 199	reduce 141
183	R/R	,	reduce 203	reduce 24
183	R/R	}	reduce 203	reduce 24
204	R/R	(	reduce 159	reduce 140
206	R/R	(	reduce 148	reduce 139
207	R/R	(	reduce 147	reduce 139
208	R/R	(	reduce 145	reduce 139
209	R/R	(	reduce 144	reduce 139
210	R/R	(	reduce 146	reduce 139
211	R/R	(	reduce 149	reduce 139
212	R/R	(	reduce 150	reduce 139
215	R/R	(	reduce 159	reduce 140
215	R/R	;	reduce 159	reduce 138
225	R/R	(	reduce 151	reduce 139
228	R/R	(	reduce 159	reduce 140
284	R/R	,	reduce 203	reduce 25
284	R/R	}	reduce 203	reduce 25
291	S/R	)	shift 339	reduce 165
343	R/R	(	reduce 153	reduce 139
360	S/R	ELSE	shift 369	reduce 94

#

	#     terminal symbols     #

';' '}' '{' ']' '[' ')' '(' ':'
',' '.' '?' '~' '!' '&' '|' '^'
'%' '/' '*' '-' '+' '=' '<' '>'
'++' '--' '==' '!=' '<=' '>=' '<<' '>>'
'->' '=op' '&&' '||' 'c'
INT CHAR FLOAT DOUBLE STRUCT AUTO STATIC
EXTERN RETURN GOTO IF ELSE SWITCH
BREAK CONTINUE WHILE DO FOR DEFAULT CASE
ENTRY REGISTER SIZEOF LONG SHORT UNSIGNED TYPEDEF 'l'
'm' 'n' 'o' 'p' 'q' 'r' 's'
identifier integer floatcon string

	#     precedence information     #

\< ','
\> '=' '=op'
\> '?' ':'
\< '||'
\< '&&'
\< '|'
\< '^'
\< '&'
\< '==' '!='
\< '<' '>' '<=' '>='
\< '<<' '>>'
\< '+' '-'
\< '*' '/' '%'
\> '!' '~'
\> '++' '--' SIZEOF
\< '[' '(' '.' '->'

\\

	#     external definitions     #

program:
	  program external_definition
	|

external_definition:
	  declaration
	| function_definition

function_definition:
	  function_specification function_body		{afdef(#1,#2);}

function_specification:
	  decl_specifiers function_declarator		{val=afdcl(1);}
	| function_declarator				{val=afdcl(0);}

function_body:
	  formal_declarations compound_statement	{val=#2;}

formal_declarations:
	  formal_decl_list				{afpdcl();}
	| 						{afpdcl();}

compound_statement:
	  begin declaration_list statement_list end	{val=#3;}
	| begin statement_list end			{val=#2;}

init_declarator_list:
	  init_declarator
	| init_declarator_list ',' init_declarator 

init_declarator:
	  $declarator initializer		{aidecl();}
	| declarator				{aidecl();}
	| function_declarator			{adeclr(maktyp());}

initializer:
	  initial_value
	| '{' initial_value_expression_list '}'
	| '{' initial_value_expression_list ',' '}'

initial_value_expression_list:
	  initial_value_expression
	| initial_value_expression_list ',' initial_value_expression

initial_value:
	  integer				{inz(i_int,#1);}
	| '-' integer				{inz(i_int,-#2);}
	| floatcon				{inz(i_float,#1);}
	| '-' floatcon				{inz(i_negfloat,#2);}
	| identifier				{inz(i_idn,#1);}
	| '&' identifier			{inz(i_idn,#2);}
	| string 				{inz(i_string,#1);}

initial_value_expression:
	  constant				{inz(i_int,#1);}
	| initial_value

	#     declarations     #

declaration_list:
	  declaration
	| declaration_list declaration

declaration:
	  decl_specifiers init_declarator_list ';'
	| literal_type_specifier ';'

decl_specifiers:
	  type_specifier			{attrib(-1,#1);}
	| sc_specifier type_specifier		{attrib(#1,#2);}
	| type_specifier sc_specifier		{attrib(#2,#1);}

type_specifier:
	  type_identifier
	| literal_type_specifier

literal_type_specifier:
	  INT					{val=TINT;}
	| CHAR					{val=TCHAR;}
	| FLOAT					{val=TFLOAT;}
	| DOUBLE				{val=TDOUBLE;}
	| LONG					{val=TINT;}
	| LONG INT				{val=TINT;}
	| SHORT					{val=TINT;}
	| SHORT INT				{val=TINT;}
	| LONG FLOAT				{val=TDOUBLE;}
	| UNSIGNED				{val=TINT;}
	| UNSIGNED INT				{val=TINT;}
	| struct '{' type_decl_list '}'			{val=astruct(NULL,#3);}
	| struct $identifier '{' type_decl_list '}'	{val=astruct(#2,#4);}
	| struct identifier	 			{val=aostruct(#2);}

sc_specifier:
	  AUTO					{val=c_auto;}
	| STATIC				{val=c_static;}
	| EXTERN				{val=c_extern;}
	| REGISTER				{val=c_auto;}
	| TYPEDEF				{val=c_typedef;}

declarator_list:
	  declarator
	| declarator_list ',' declarator 

declarator:
	  dclr					{val=adeclr(maktyp());}
	| identifier ':' constant		{val=adeclr(afield(#1,#3));}
	| ':' constant				{val=adeclr(afield(-1,#2));}

$declarator:
	  dclr					{aiinz(adeclr(maktyp()));}

dclr:
	'*' dclr				{val=adclr(#2,MPTR);}
	| dclr '(' ')'				{val=adclr(#1,MFUNC);}
	| dclr '[' ']'				{val=adclr(#1,MARRAY,1);}
	| dclr '[' constant ']'			{val=adclr(#1,MARRAY,#3);}
	| identifier  				{val=adclr(0,0);}
	| '(' dclr ')' 				{val=#2;}

function_declarator:
	  '*' function_declarator		{val=adclr(#2,MPTR);}
	| function_declarator '(' ')'		{val=adclr(#1,MFUNC);}
	| function_declarator '[' ']'		{val=adclr(#1,MARRAY,1);}
	| function_declarator '[' constant ']'	{val=adclr(#1,MARRAY,#3);}
	| identifier '(' ')'			{val=adclr(adclr(0,0),MFUNC);
							parml=0;}
	| identifier '(' parameter_list ')'	{val=adclr(adclr(0,0),MFUNC);
							parml=#3;}
	| '(' function_declarator ')'		{val=#2;}

parameter_list:
	  identifier				{val=push(#1);}
	| parameter_list ',' identifier		{push(#3);}

formal_decl_list:
	  formal_declaration
	| formal_decl_list formal_declaration

formal_declaration:
	  type_declaration
	| REGISTER type_declaration

type_decl_list:
	  type_declaration
	| type_decl_list type_declaration

type_declaration:
	  $type_specifier declarator_list ';'	{in_type_def=0;
						val=#2;}

$type_specifier:
	  type_specifier			{in_type_def=1;
						attrib(-1,#1);}

	#     statements     #

statement_list:
	  statement
	| statement_list statement		{val=astmtl(#1,#2);}

statement:
	  expression  ';'					{val=aexprstmt(#1);}
	| compound_statement
	| IF '(' expression ')' statement	 		{val=aif(#3,#5,0);}
	| IF '(' expression ')' statement ELSE statement	{val=aif(#3,#5,#7);}
	| while '(' expression ')' statement	 		{val=awhile(#3,#5);}
	| for '(' .expression ';' .expression ';' .expression ')' statement
								{val=afor(#3,#5,#7,#9);}
	| do statement WHILE '(' expression ')' ';'		{val=ado(#2,#5);}
	| switch '(' expression ')' statement			{val=aswitch(#3,#5);}
	| CASE constant ':' statement				{val=acase(#2,#4);}
	| DEFAULT ':' statement					{val=adefault(#3);}
	| BREAK ';'						{val=abreak();}
	| CONTINUE ';'						{val=acontinue();}
	| RETURN ';'						{val=areturn(0);}
	| RETURN expression ';'					{val=areturn(#2);}
	| GOTO lexpression ';'					{val=agoto(#2);}
	| identifier ':' statement				{val=alabel(#1,#3);}
	| ENTRY identifier ':' statement			{val=aentry(#2,#4);}
	| ';' 							{val=anull();} 


	#     expressions     #

.expression:
	  expression
	|			{val=0;}

expression_list:
	  expression	\= '='
	| expression_list ',' expression 		{val=aelist(#1,#3);}

expression:
	  expression '*' expression		{val=node(n_times,#1,#3);}
	| expression '/' expression		{val=node(n_div,#1,#3);}
	| expression '%' expression		{val=node(n_mod,#1,#3);}
	| expression '+' expression		{val=node(n_plus,#1,#3);}
	| expression '-' expression		{val=node(n_minus,#1,#3);}
	| expression '<<' expression		{val=node(n_ls,#1,#3);}
	| expression '>>' expression		{val=node(n_rs,#1,#3);}
	| expression '<' expression		{val=node(n_lt,#1,#3);}
	| expression '>' expression		{val=node(n_gt,#1,#3);}
	| expression '<=' expression		{val=node(n_le,#1,#3);}
	| expression '>='  expression		{val=node(n_ge,#1,#3);}
	| expression '=='  expression		{val=node(n_eq,#1,#3);}
	| expression '!='  expression		{val=node(n_ne,#1,#3);}
	| expression '&' expression		{val=node(n_band,#1,#3);}
	| expression '^' expression		{val=node(n_bxor,#1,#3);}
	| expression '|' expression		{val=node(n_bior,#1,#3);}
	| expression '&&' expression		{val=node(n_tv_and,#1,#3);}
	| expression '||' expression		{val=node(n_tv_or,#1,#3);}
	| expression '?' expression ':' expression
				{val=node(n_qmark,#1,node(n_colon,#3,#5));}
	| expression '=' expression		{val=node(n_assign,#1,#3);}
	| expression '=op' expression		{val=node(n_ars+#2,#1,#3);}
	| expression ',' expression		{val=node(n_comma,#1,#3);}
	| term 

# the following productions are ordered very carefully so that the
  desired thing is done in the case of a R/R conflict #

lexpression:
	  expression
	| identifier			{val=aidn(alidn(#1));}

fterm:
	  term
	| identifier			{val=aidn(afidn(#1));}

type_identifier:
	  identifier			{val=atidn(#1);}

term:
	  term '++'			{val=node(n_inca,#1);}
	| term '--'			{val=node(n_deca,#1);}
	| '*' term			{val=node(n_star,#2);}
	| '&' term			{val=node(n_addr,#2);}
	| '-' term			{val=node(n_uminus,#2);}
	| '!' term			{val=node(n_tvnot,#2);}
	| '~' term			{val=node(n_bnot,#2);}
	| '++' term			{val=node(n_incb,#2);}
	| '--' term			{val=node(n_decb,#2);}
	| SIZEOF term			{val=node(n_sizeof,#2);}
	| SIZEOF '(' cast_type ')' \= SIZEOF
					{val=node(n_int,1);} # hack #
	| '(' cast_type ')' term \= '++'
					{val=#4;} # hack #
	| term '[' expression ']'	{val=asubscript(#1,#3);}
	| fterm '(' expression_list ')'	{val=acall(#1,#3);}
	| fterm '(' ')'			{val=acall(#1,0);}
	| term '.' identifier		{val=adot(#1,#3);}
	| term '->' identifier		{val=aptr(#1,#3);}
	| identifier			{val=aidn(aeidn(#1));}
	| integer			{val=node(n_int,#1);}
	| floatcon			{val=node(n_float,#1);}
	| string			{val=node(n_string,#1);}
	| '(' expression ')' 		{val=#2;}

cast_type:	   literal_type_specifier null_decl

null_decl:	   # empty #
		|  '(' ')'
		|  '(' null_decl ')' '(' ')'
		|  '*' null_decl
		|  null_decl '[' ']'
		|  null_decl '[' constant ']'
		|  '(' null_decl ')'

while:		  WHILE			{apshw();}
do:		  DO			{apshd();}
for:		  FOR			{apshf();}
switch:		  SWITCH		{apshs();}
struct:		  STRUCT		{strlev++;}
$identifier:	  identifier		{val=astridn(#1);}
begin:		  '{'			{abegin();}
end:		  '}'			{aend();}

constant:
	  constant '*' constant		{val=#1*#3;}
	| constant '/' constant		{val=#1/#3;}
	| constant '%' constant		{val=#1%#3;}
	| constant '+' constant		{val=#1+#3;}
	| constant '-' constant		{val=#1-#3;}
	| constant '<<' constant	{val=#1<<#3;}
	| constant '>>' constant	{val=#1>>#3;}
	| constant '<' constant		{val=#1<#3;}
	| constant '>' constant		{val=#1>#3;}
	| constant '<=' constant	{val=#1<=#3;}
	| constant '>='  constant	{val=#1>=#3;}
	| constant '=='  constant	{val=#1==#3;}
	| constant '!='  constant	{val=#1!=#3;}
	| constant '&' constant		{val=#1&#3;}
	| constant '^' constant		{val=#1^#3;}
	| constant '|' constant		{val=#1|#3;}
	| constant '&&' constant	{val=#1&&#3;}
	| constant '||' constant	{val=#1||#3;}
	| constant '?' constant ':' constant
					{val=(#1?#3:#5);}
	| c_term 

c_term:
	  '-' c_term		{val= -#2;}
	| '!' c_term		{val= !#2;}
	| '~' c_term		{val= ~#2;}
	| integer
	| '(' constant ')'	{val=#2;}


             reply	other threads:[~2018-10-28 21:54 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-28 21:34 Lars Brinkhoff [this message]
2018-10-29  3:00 ` Steve Johnson
2018-10-29  7:31   ` Lars Brinkhoff
2018-10-29 17:52     ` Steve Johnson
2018-10-29 18:37       ` Warner Losh
2018-10-30  8:16         ` Lars Brinkhoff
2018-11-03 21:50           ` Steve Johnson
2018-10-29 19:02       ` David
2018-10-30 22:01         ` Steve Johnson
2018-10-31  0:58           ` Larry McVoy
2018-10-31 13:49             ` Clem Cole
2018-11-03 22:14             ` Steve Johnson
2018-10-31  6:09           ` Lars Brinkhoff
2018-10-31 15:39 Noel Chiappa

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7wsh0piwli.fsf@junk.nocrew.org \
    --to=lars@nocrew.org \
    --cc=tuhs@tuhs.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).