[TUHS] Archaic yacc C grammar

Steve Johnson scj at yaccman.com
Mon Oct 29 13:00:42 AEST 2018


I don't recognize this as any Yacc that my hands have touched.   
Looking at the reserved words,
there is one, ENTRY, that I've never heard of (although FORTRAN had an
ENTRY statement), 

and there is STRUCT but no UNION.  Also, he uses val= instead of
$$=.  There don't seem to be 

any nontrivial assignment ops (neither += or =+).

Al was at Bell Labs in 1973, and this is dated 5 years later.

The use of quotes for single character literals was in early Yaccs,
but it led to some strange-looking 

lexical analyzer code, and I quickly gave it up.

I'm guessing either Al wrote it from scratch or based it on some other
similar program.  LR parsing
made quite a stir in the 70's.

Can't help you though as far as how to generate a parser from this
input...

Steve

----- Original Message -----
From: "Lars Brinkhoff" <lars at nocrew.org>
To:<tuhs at tuhs.org>
Cc:
Sent:Sun, 28 Oct 2018 21:34:49 +0000
Subject:[TUHS] Archaic yacc C grammar

 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}
 | constant '^' constant {val=#1^#3;}
 | constant '|' constant {val=#1|#3;}
 | constant '&&' constant {val=#1&}
 | 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;}


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://minnie.tuhs.org/pipermail/tuhs/attachments/20181028/8199abae/attachment.html>


More information about the TUHS mailing list