The Unix Heritage Society mailing list
 help / color / mirror / Atom feed
From: "Steve Johnson" <scj@yaccman.com>
To: "Lars Brinkhoff" <lars@nocrew.org>, tuhs@tuhs.org
Subject: Re: [TUHS] Archaic yacc C grammar
Date: Sun, 28 Oct 2018 20:00:42 -0700	[thread overview]
Message-ID: <1dbc3d888e7be7a2c93e497eac14bcd9f43c72fc@webmail.yaccman.com> (raw)
In-Reply-To: <7wsh0piwli.fsf@junk.nocrew.org>

[-- Attachment #1: Type: text/plain, Size: 12516 bytes --]


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@nocrew.org>
To:<tuhs@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;}



[-- Attachment #2: Type: text/html, Size: 15539 bytes --]

  reply	other threads:[~2018-10-29 10:02 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-28 21:34 Lars Brinkhoff
2018-10-29  3:00 ` Steve Johnson [this message]
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=1dbc3d888e7be7a2c93e497eac14bcd9f43c72fc@webmail.yaccman.com \
    --to=scj@yaccman.com \
    --cc=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).