[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