[cig-commits] r5996 - in cs/babel/trunk: . buffy buffy/examples

leif at geodynamics.org leif at geodynamics.org
Fri Feb 9 20:30:11 PST 2007


Author: leif
Date: 2007-02-09 20:30:11 -0800 (Fri, 09 Feb 2007)
New Revision: 5996

Added:
   cs/babel/trunk/buffy/
   cs/babel/trunk/buffy/examples/
   cs/babel/trunk/buffy/examples/example-9-1.bff
   cs/babel/trunk/buffy/examples/example-9-2.bff
   cs/babel/trunk/buffy/examples/example-9-3.bff
   cs/babel/trunk/buffy/gram.y
   cs/babel/trunk/buffy/main.c
   cs/babel/trunk/buffy/scan.l
Log:
Created a grammar for Buffy.

The grammar and examples are taken directly from "Users' Reference to
B" by Ken Thompson:

    http://cm.bell-labs.com/cm/cs/who/dmr/kbman.html

My YACC translation of the grammar isn't exactly perfect, but its good
enough to parse the examples.

B (the predecessor to C) is a typeless language -- or, more precisely,
all variables have the same type.  B code looks roughly like C code
stripped of type declarations.  This typelessness makes the syntax
ideal for duck typing -- and thus an ideal starting point for our new
language.


Added: cs/babel/trunk/buffy/examples/example-9-1.bff
===================================================================
--- cs/babel/trunk/buffy/examples/example-9-1.bff	2007-02-10 00:37:05 UTC (rev 5995)
+++ cs/babel/trunk/buffy/examples/example-9-1.bff	2007-02-10 04:30:11 UTC (rev 5996)
@@ -0,0 +1,14 @@
+
+/* The following function will print a non-negative number, n, to
+  the base b, where 2<=b<=10,  This routine uses the fact that
+  in the ANSCII character set, the digits 0 to 9 have sequential
+  code values.  */
+
+printn(n,b) {
+    extrn putchar;
+    auto a;
+
+    if(a=n/b) /* assignment, not test for equality */
+        printn(a, b); /* recursive */
+    putchar(n%b + '0');
+}

Added: cs/babel/trunk/buffy/examples/example-9-2.bff
===================================================================
--- cs/babel/trunk/buffy/examples/example-9-2.bff	2007-02-10 00:37:05 UTC (rev 5995)
+++ cs/babel/trunk/buffy/examples/example-9-2.bff	2007-02-10 04:30:11 UTC (rev 5996)
@@ -0,0 +1,33 @@
+
+/* The following program will calculate the constant e-2 to about
+   4000 decimal digits, and print it 50 characters to the line in
+   groups of 5 characters.  The method is simple output conversion
+   of the expansion
+     1/2! + 1/3! + ... = .111....
+   where the bases of the digits are 2, 3, 4, . . . */
+
+main() {
+    extrn putchar, n, v;
+    auto i, c, col, a;
+
+    i = col = 0;
+    while(i<n)
+        v[i++] = 1;
+    while(col<2*n) {
+        a = n+1 ;
+        c = i = 0;
+        while (i<n) {
+            c =+ v[i] *10;
+            v[i++]  = c%a;
+            c =/ a--;
+        }
+
+        putchar(c+'0');
+        if(!(++col%5))
+            putchar(col%50?' ': '*n');
+    }
+    putchar('*n*n');
+}
+
+v[2000];
+n 2000;

Added: cs/babel/trunk/buffy/examples/example-9-3.bff
===================================================================
--- cs/babel/trunk/buffy/examples/example-9-3.bff	2007-02-10 00:37:05 UTC (rev 5995)
+++ cs/babel/trunk/buffy/examples/example-9-3.bff	2007-02-10 04:30:11 UTC (rev 5996)
@@ -0,0 +1,55 @@
+
+/* The following function is a general formatting, printing, and
+   conversion subroutine.  The first argument is a format string.
+   Character sequences of the form `%x' are interpreted and cause
+   conversion of type 'x' of the next argument, other character
+   sequences are printed verbatim.   Thus
+
+    printf("delta is %d*n", delta);
+
+    will convert the variable delta to decimal (%d) and print the
+    string with the converted form of delta in place of %d.   The
+    conversions %d-decimal, %o-octal, *s-string and %c-character
+    are allowed.
+
+    This program calls upon the function `printn'. (see section
+    9.1) */
+
+printf(fmt, x1,x2,x3,x4,x5,x6,x7,x8,x9) {
+    extrn printn, char, putchar;
+    auto adx, x, c, i, j;
+
+    i= 0;    /* fmt index */
+    adx = &x1;    /* argument pointer */
+loop :
+    while((c=char(fmt,i++) ) != '%') {
+        if(c == '*e')
+            return;
+        putchar(c);
+    }
+    x = *adx++;
+    switch c = char(fmt,i++) {
+
+    case 'd': /* decimal */
+    case 'o': /* octal */
+        if(x < 0) {
+            x = -x ;
+            putchar('-');
+        }
+        printn(x, c=='o'?8:10);
+        goto loop;
+
+    case 'c' : /* char */
+        putchar(x);
+        goto loop;
+
+    case 's': /* string */
+        while((c=char(x, j++)) != '*e')
+            putchar(c);
+        goto loop;
+    }
+    putchar('%') ;
+    i--;
+    adx--;
+    goto loop;
+}

Added: cs/babel/trunk/buffy/gram.y
===================================================================
--- cs/babel/trunk/buffy/gram.y	2007-02-10 00:37:05 UTC (rev 5995)
+++ cs/babel/trunk/buffy/gram.y	2007-02-10 04:30:11 UTC (rev 5996)
@@ -0,0 +1,160 @@
+%{
+
+#define YYSTYPE int
+
+%}
+
+%token NAME CONSTANT CHAR_CONSTANT STRING_CONSTANT
+%token INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
+
+%token EXTRN AUTO
+
+%token CASE IF ELSE SWITCH WHILE GOTO RETURN
+
+%start program
+%%
+
+program
+	: definition_list
+	;
+
+definition_list
+	: definition
+	| definition_list definition
+	;
+
+definition
+	: name ';'
+	| name ival ';'
+	| name '[' ']' ';'
+	| name '[' ']' ival_list ';'
+	| name '[' constant ']' ';'
+	| name '[' constant ']' ival_list ';'
+	| name '(' ')' statement
+	| name '(' name_list ')' statement
+	;
+
+ival_list
+	: ival
+	| ival_list ',' ival
+	;
+
+ival
+	: constant
+	| name
+	;
+
+statement
+	: AUTO decl_list ';' statement
+	| EXTRN name_list ';'
+	| name ':' statement
+	| CASE constant ':' statement
+	| '{' statement_list '}'
+	| IF '(' rvalue ')' statement
+	| IF '(' rvalue ')' statement ELSE statement
+	| WHILE '(' rvalue ')' statement
+	| SWITCH rvalue statement
+	| GOTO rvalue ';'
+	| RETURN ';'
+	| RETURN rvalue ';'
+	| rvalue ';'
+	| ';'
+	;
+
+decl_list
+	: decl
+	| decl_list ',' decl
+	;
+
+decl
+	: name
+	| name constant
+	;
+
+name_list
+	: name
+	| name_list ',' name
+	;
+
+statement_list
+	: statement
+	| statement_list statement
+	;
+
+rvalue
+	: '(' rvalue ')'
+	| lvalue
+	| constant
+	| lvalue assign rvalue
+	| inc_dec lvalue
+	| lvalue inc_dec
+	| '-' rvalue
+	| '!' rvalue
+	| '&' lvalue
+	| rvalue binary rvalue
+	| rvalue '?' rvalue ':' rvalue
+	| rvalue '(' ')'
+	| rvalue '(' rvalue_list ')'
+	;
+
+rvalue_list
+	: rvalue
+	| rvalue_list ',' rvalue
+	;
+
+assign
+	: '='
+	| '=' binary
+	;
+
+inc_dec
+	: INC_OP
+	| DEC_OP
+	;
+
+binary
+	: '|'
+	| '&'
+	| EQ_OP
+	| NE_OP
+	| '<'
+	| LE_OP
+	| '>'
+	| GE_OP
+	| LEFT_OP
+	| RIGHT_OP
+	| '-'
+	| '+'
+	| '%'
+	| '*'
+	| '/'
+	;
+
+lvalue
+	: name
+	| '*' rvalue
+	| lvalue '[' rvalue ']' /* should be "rvalue[rvalue]", but this leads to 36 reduce/reduce conflicts */
+	;
+
+constant
+	: CONSTANT
+	| CHAR_CONSTANT
+	| STRING_CONSTANT
+	;
+
+name
+	: NAME
+	;
+%%
+
+#include <stdio.h>
+
+extern char yytext[];
+extern int column;
+
+yyerror(s)
+char *s;
+{
+	fflush(stdout);
+	printf("\n%*s\n%*s\n", column, "^", column, s);
+}

Added: cs/babel/trunk/buffy/main.c
===================================================================
--- cs/babel/trunk/buffy/main.c	2007-02-10 00:37:05 UTC (rev 5995)
+++ cs/babel/trunk/buffy/main.c	2007-02-10 04:30:11 UTC (rev 5996)
@@ -0,0 +1,11 @@
+
+#include <stdio.h>
+
+int yyparse();
+
+int main(int argc, char **argv)
+{
+    return yyparse();
+}
+
+/* end of file */

Added: cs/babel/trunk/buffy/scan.l
===================================================================
--- cs/babel/trunk/buffy/scan.l	2007-02-10 00:37:05 UTC (rev 5995)
+++ cs/babel/trunk/buffy/scan.l	2007-02-10 04:30:11 UTC (rev 5996)
@@ -0,0 +1,104 @@
+D			[0-9]
+L			[a-zA-Z_]
+
+%{
+#include <stdio.h>
+#include "gram.h"
+
+void count();
+%}
+
+%%
+"/*"			{ comment(); }
+
+"auto"			{ count(); return(AUTO); }
+"case"			{ count(); return(CASE); }
+"else"			{ count(); return(ELSE); }
+"extrn"			{ count(); return(EXTRN); }
+"goto"			{ count(); return(GOTO); }
+"if"			{ count(); return(IF); }
+"return"		{ count(); return(RETURN); }
+"switch"		{ count(); return(SWITCH); }
+"while"			{ count(); return(WHILE); }
+
+{L}({L}|{D})*		{ count(); return(NAME); }
+
+{D}+			{ count(); return(CONSTANT); }
+'(\\.|[^\\'])+'		{ count(); return(CHAR_CONSTANT); }
+
+\"(\\.|[^\\"])*\"	{ count(); return(STRING_CONSTANT); }
+
+">>"			{ count(); return(RIGHT_OP); }
+"<<"			{ count(); return(LEFT_OP); }
+"++"			{ count(); return(INC_OP); }
+"--"			{ count(); return(DEC_OP); }
+"<="			{ count(); return(LE_OP); }
+">="			{ count(); return(GE_OP); }
+"=="			{ count(); return(EQ_OP); }
+"!="			{ count(); return(NE_OP); }
+";"			{ count(); return(';'); }
+"{"			{ count(); return('{'); }
+"}"			{ count(); return('}'); }
+","			{ count(); return(','); }
+":"			{ count(); return(':'); }
+"="			{ count(); return('='); }
+"("			{ count(); return('('); }
+")"			{ count(); return(')'); }
+"["			{ count(); return('['); }
+"]"			{ count(); return(']'); }
+"&"			{ count(); return('&'); }
+"!"			{ count(); return('!'); }
+"-"			{ count(); return('-'); }
+"+"			{ count(); return('+'); }
+"*"			{ count(); return('*'); }
+"/"			{ count(); return('/'); }
+"%"			{ count(); return('%'); }
+"<"			{ count(); return('<'); }
+">"			{ count(); return('>'); }
+"|"			{ count(); return('|'); }
+"?"			{ count(); return('?'); }
+
+[ \t\v\n\f]		{ count(); }
+.			{ /* ignore bad characters */ }
+
+%%
+
+yywrap()
+{
+	return(1);
+}
+
+comment()
+{
+	char c, c1;
+
+loop:
+	while ((c = input()) != '*' && c != 0)
+		putchar(c);
+
+	if ((c1 = input()) != '/' && c != 0)
+	{
+		/*unput(c1);*/
+		goto loop;
+	}
+
+	if (c != 0)
+		putchar(c1);
+}
+
+int column = 0;
+
+void count()
+{
+	int i;
+
+	for (i = 0; yytext[i] != '\0'; i++)
+		if (yytext[i] == '\n')
+			column = 0;
+		else if (yytext[i] == '\t')
+			column += 8 - (column % 8);
+		else
+			column++;
+
+	ECHO;
+}



More information about the cig-commits mailing list