diff tests/agcl/contrib/yabasic.syn @ 0:13d2b8934445

Import AnaGram (near-)release tree into Mercurial.
author David A. Holland
date Sat, 22 Dec 2007 17:52:45 -0500
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/agcl/contrib/yabasic.syn	Sat Dec 22 17:52:45 2007 -0500
@@ -0,0 +1,584 @@
+{
+
+/*
+     YABASIC --- a tiny integrated Basic Compiler/Interpreter
+
+     BISON - part
+
+     this Program is subject to the GNU General Public License;
+     see the file yabasic.c for details.
+*/
+
+
+//#undef WINDOWS
+#include "yabasic.h"     /* definitions of yabasic */
+#include <malloc.h>
+
+#if HAVE_ALLOCA_H
+#include <alloca.h>
+#endif
+
+void __yy_bcopy(char *,char *,int); /* prototype missing */
+
+int yylineno=1;
+int yylex(void);
+
+char *popString(int);
+void pushChar(int);
+
+}
+
+[
+  ~case sensitive
+  disregard white space
+  lexeme {digit string, name, STRING, STRSYM, number}
+  distinguish lexemes
+  parser name = parseBasic
+  line numbers
+  escape backslashes
+]
+
+white space = ' ' + '\t'
+
+//(double *) step_part
+
+
+SEP
+ -> ["REM", ~(eof + white space + '\n')?...], '\n'      ={
+     yylineno++;
+     if (interactive) PCB.exit_flag = AG_SUCCESS_CODE;
+     return;
+ }
+
+(double) number
+ -> simple real
+ -> simple real:x, 'e'+'E', '+'?,exponent:e            =x*pow(10,e);
+ -> simple real:x, 'e'+'E', '-',exponent:e            =x*pow(10,-e);
+
+(double) simple real
+ -> integer part:i, '.', fraction part:f                      = i+f;
+ -> integer part, '.'?
+ -> '.', fraction part:f                                        = f;
+
+(double) integer part
+ -> digit:d                                                 = d-'0';
+ -> integer part:x, digit:d                          = 10*x + d-'0';
+
+(double) fraction part
+ -> digit:d                                            =(d-'0')/10.;
+ -> digit:d, fraction part:f                       =(d-'0' + f)/10.;
+
+(int) exponent
+ -> digit:d                                                 = d-'0';
+ -> exponent:x, digit:d                              = 10*x + d-'0';
+
+(int) name           //value of name token is length of name string
+ -> letter: c                                       =pushChar(c), 1;
+ -> name:k, letter+digit: c                       =pushChar(c), k+1;
+
+
+(char *) SYMBOL
+  -> name:k                                   =strdup(popString(k));
+
+(char *) STRSYM
+  -> name:k, '$'                              =pushChar('$'), strdup(popString(k+1));
+
+(char *) DIGITS
+  -> digit string:k                                  =strdup(popString(k));
+
+(int) digit string
+ -> digit:d                                         =pushChar(d), 1;
+ -> digit string:k, digit:d                         =pushChar(d), k+1;
+
+(char *) STRING
+ -> '"', string text:k, '"'                         =strdup(popString(k));
+ -> '"', string text:k, '\n'                        =strdup(popString(k));
+
+(int) string text
+ ->                                                 =0;
+ -> string text:k, ~(eof + '"' + '\n'):c            =pushChar(c), k+1;
+ -> string text:k, "\\\""                           =pushChar('"'), k+1;
+
+/*
+[
+  left {"OR"}
+  left {"AND"}
+  left {"NOT"}
+  left {'-', '+'}
+  left {'*', '/'}
+  left {'^'}
+  nonassoc {UMINUS}
+]
+*/
+
+letter = 'a-z' + 'A-Z'
+digit  = '0-9'
+eof = 0 + -1
+
+
+program $
+ -> statement list, eof             =end_of_file = TRUE;
+
+statement list
+ ->
+/*
+ -> statement_list, !{
+if (errorlevel<=ERROR) {YYABORT;}},
+   SEP, !{
+yylineno+=$3;},
+   statement
+*/
+ -> statement list, SEP, statement
+ -> statement list, SEP, label, statement
+
+label
+ -> "LABEL", SYMBOL:s                =create_label(s);
+ -> DIGITS:s                         =create_label(s);
+
+
+statement  /* empty */
+ ->
+ -> string_assignment
+ -> assignment
+ -> for_loop
+ -> if_clause
+ -> "GOTO", symbol_or_lineno:s ={create_goto(s);}
+ -> "GOSUB", symbol_or_lineno:s ={create_gosub(s);}
+ -> "ON", "INTERRUPT", "BREAK" ={create_exception(TRUE);}
+ -> "ON", "INTERRUPT", "CONTINUE" ={create_exception(FALSE);}
+ -> "ON", expression, "GOTO", !{create_skipper();}, goto_list ={create_nop();}
+ -> "ON", expression, "GOSUB", !{create_skipper();}, gosub_list ={create_nop();}
+// -> LABEL, symbol_or_lineno ={create_label($2);}
+ -> "OPEN", hashed_number:n, ',', string expression, ',', string expression ={create_myopen(n,'+');}
+ -> "OPEN", hashed_number:n, ',', string expression ={create_myopen(n,'-');}
+ -> "CLOSE", hashed_number:n ={create_myclose(n);}
+ -> "PRINT", printintro, printlist, !{
+create_revert(FALSE);},
+   semicolon
+ -> "INPUT", inputintro, inputlist =lastinput->args=0;
+ -> "READ", readlist
+ -> "DATA", datalist
+ -> "RESTORE" =create_restore("");
+ -> "RESTORE", symbol_or_lineno:s =create_restore(s);
+ -> "RETURN" ={create_return();}
+ -> "DIM", dimlist
+ -> "OPEN", "WINDOW", expression, ',', expression =create_openwin(FALSE);
+ -> "OPEN", "WINDOW", expression, ',', expression, ',', string expression ={create_openwin(TRUE);}
+ -> "DOT", mapping                    =create_dot();
+ -> "LINE", mapping, "TO", mapping =create_line('l');
+ -> "CIRCLE", mapping, ',', expression =create_circle();
+ -> "TEXT", string expression, ',', mapping =create_text(TRUE);
+ -> "TEXT", mapping, ',', string expression =create_text(FALSE);
+ -> "MAP", expression, ',', expression, ',', expression, ',', expression, "TO", expression, ',', expression, ',', expression, ',', expression =create_makemap();
+ -> "ARROW", mapping, "TO", mapping =create_line('a');
+ -> "XTICK", mapping, ',', string expression =create_tick(1);
+ -> "YTICK", mapping, ',', string expression =create_tick(3);
+ -> "XTICK", mapping =create_tick(0);
+ -> "YTICK", mapping =create_tick(2);
+ -> "CLOSE", "WINDOW" =create_closewin();
+ -> "CLEAR", "WINDOW" =create_clearwin();
+ -> "CLEAR", "SCREEN" =create_clearscreen();
+ -> "OPEN", "PRINTER" =create_openprinter(0);
+ -> "OPEN", "PRINTER", string expression =create_openprinter(1);
+ -> "CLOSE", "PRINTER" =create_closeprinter();
+ -> "WAIT", expression =create_mywait();
+ -> "BELL" =create_bell();
+ -> "INKEY" ={create_function(MYINKEY); create_popstrsym(NULL);}
+ -> "SYSTEM2", '(', string expression, ')' ={create_function(MYSYSTEM2);
+	create_popdblsym(NULL);}
+ -> "POKE", string expression, ',', string expression ={create_poke('s');}
+ -> "POKE", string expression, ',', expression ={create_poke('d');}
+ -> "END" ={create_myend();}
+
+string_assignment
+ -> STRSYM:s, '=', string expression ={create_popstrsym(s);}
+ -> "MID", '(', STRSYM:s, !{
+create_pushstrptr(s);},
+   ',', expression, ',', expression, ')', '=', string expression ={create_changestring(MYMID);}
+ -> "LEFT", '(', STRSYM:s, !{
+create_pushstrptr(s);},
+   ',', expression, ')', '=', string expression ={create_changestring(MYLEFT);}
+ -> "RIGHT", '(', STRSYM:s, !{
+create_pushstrptr(s);},
+   ',', expression, ')', '=', string expression ={create_changestring(MYRIGHT);}
+ -> STRSYM:s, '(', !{
+pushcounter();},
+   indexlist, ')', '=', string expression ={create_doarray(s,ASSIGNSTRINGARRAY);}
+ -> "MID", '(', STRSYM:s, '(', !{
+pushcounter();},
+   indexlist, ')', !{
+create_doarray(s,GETSTRINGPOINTER);},
+   ',', expression, ',', expression, ')', '=', string expression ={create_changestring(MYMID);}
+ -> "LEFT", '(', STRSYM:s, '(', !{
+pushcounter();},
+   indexlist, ')', !{
+create_doarray(s,GETSTRINGPOINTER);},
+   ',', expression, ')', '=', string expression ={create_changestring(MYLEFT);}
+ -> "RIGHT", '(', STRSYM:s, '(', !{
+pushcounter();},
+   indexlist, ')', !{
+create_doarray(s,GETSTRINGPOINTER);},
+   ',', expression, ')', '=', string expression ={create_changestring(MYRIGHT);}
+
+string expression
+ -> primary string expression
+ -> string expression, '+', primary string expression ={create_concat();}
+
+primary string expression
+ -> STRSYM:s ={create_pushstrsym(s);}
+ -> string_function
+ -> STRING:s ={if (s==NULL) {error(ERROR,"String not terminated");create_pushstr("");} else {create_pushstr(s);}}
+ -> STRSYM:s, '(', !{
+pushcounter();},
+   indexlist, ')' ={create_doarray(s,CALLSTRINGARRAY);}
+ -> '(', string expression, ')'
+
+string_function
+ -> "LEFT", '(', string expression, ',', expression, ')' ={create_function(MYLEFT);}
+ -> "RIGHT", '(', string expression, ',', expression, ')' ={create_function(MYRIGHT);}
+ -> "MID", '(', string expression, ',', expression, ',', expression, ')' ={create_function(MYMID);}
+ -> "STR", '(', expression, ')' ={create_function(MYSTR);}
+ -> "STR", '(', expression, ',', string expression, ')' ={create_function(MYSTR2);}
+ -> "INKEY" ={create_function(MYINKEY);}
+ -> "CHR", '(', expression, ')' ={create_function(MYCHR);}
+ -> "UPPER", '(', string expression, ')' ={create_function(MYUPPER);}
+ -> "LOWER", '(', string expression, ')' ={create_function(MYLOWER);}
+ -> "LTRIM", '(', string expression, ')' ={create_function(MYLTRIM);}
+ -> "RTRIM", '(', string expression, ')' ={create_function(MYRTRIM);}
+ -> "TRIM", '(', string expression, ')' ={create_function(MYTRIM);}
+ -> "SYSTEM", '(', string expression, ')' ={create_function(MYSYSTEM);}
+ -> "DATE" ={create_function(MYDATE);}
+ -> "TIME" ={create_function(MYTIME);}
+ -> "PEEK2", '(', string expression, ')' ={create_function(MYPEEK2);}
+
+assignment
+ -> SYMBOL:s, '=', expression ={create_popdblsym(s);}
+ -> SYMBOL:s, '(', !{
+pushcounter();},
+   indexlist, ')', '=', expression ={create_doarray(s,ASSIGNARRAY);}
+
+primary expression
+ -> number:n                           =create_pushdbl(n);
+ -> function
+ -> SYMBOL:s                           =create_pushdblsym(s);
+ -> SYMBOL:s, '(', !pushcounter();,
+      indexlist, ')'                   ={create_doarray(s,CALLARRAY);}
+ -> '(', expression, ')'
+ -> '-', primary expression /* 1ef4:fa2arec <֠ */ ={create_negate();}
+
+exponential expression
+ -> primary expression
+ -> exponential expression, '^', primary expression ={create_dblbin('^');}
+
+multiplicative expression
+ -> exponential expression
+ -> multiplicative expression, '*', exponential expression ={create_dblbin('*');}
+ -> multiplicative expression, '/', exponential expression ={create_dblbin('/');}
+
+expression
+ -> multiplicative expression
+ -> expression, '+', multiplicative expression ={create_dblbin('+');}
+ -> expression, '-', multiplicative expression ={create_dblbin('-');}
+
+/*
+ -> expression, '+', expression ={create_dblbin('+');}
+ -> expression, '-', expression ={create_dblbin('-');}
+ -> expression, '*', expression ={create_dblbin('*');}
+ -> expression, '/', expression ={create_dblbin('/');}
+ -> expression, '^', expression ={create_dblbin('^');}
+ -> '-', expression /* 1ef4:fa2arec <֠ * / ={create_negate();}
+*/
+
+mapping
+ -> expression, ',', expression
+ -> "MAP", '(', expression, ',', expression, ')' ={create_map();}
+
+function
+ -> "SIN", '(', expression, ')' ={create_function(MYSIN);}
+ -> "ASIN", '(', expression, ')' ={create_function(MYASIN);}
+ -> "COS", '(', expression, ')' ={create_function(MYCOS);}
+ -> "ACOS", '(', expression, ')' ={create_function(MYACOS);}
+ -> "TAN", '(', expression, ')' ={create_function(MYTAN);}
+ -> "ATAN", '(', expression, ')' ={create_function(MYATAN);}
+ -> "ATAN", '(', expression, ',', expression, ')' ={create_function(MYATAN2);}
+ -> "EXP", '(', expression, ')' ={create_function(MYEXP);}
+ -> "LOG", '(', expression, ')' ={create_function(MYLOG);}
+ -> "SQRT", '(', expression, ')' ={create_function(MYSQRT);}
+ -> "INT", '(', expression, ')' ={create_function(MYINT);}
+ -> "FRAC", '(', expression, ')' ={create_function(MYFRAC);}
+ -> "MOD", '(', expression, ',', expression, ')' ={create_function(MYMOD);}
+ -> "RAN", '(', expression, ')' ={create_function(MYRAN);}
+ -> "RAN", '(', ')' ={create_function(MYRAN2);}
+ -> "MIN", '(', expression, ',', expression, ')' ={create_function(MYMIN);}
+ -> "MAX", '(', expression, ',', expression, ')' ={create_function(MYMAX);}
+ -> "XMAP", '(', expression, ')' ={create_function(MYXMAP);}
+ -> "YMAP", '(', expression, ')' ={create_function(MYYMAP);}
+ -> "LEN", '(', string expression, ')' ={create_function(MYLEN);}
+ -> "VAL", '(', string expression, ')' ={create_function(MYVAL);}
+ -> "ASC", '(', string expression, ')' ={create_function(MYASC);}
+ -> "INSTR", '(', string expression, ',', string expression, ')' ={create_function(MYINSTR);}
+ -> "SYSTEM2", '(', string expression, ')' ={create_function(MYSYSTEM2);}
+ -> "PEEK", '(', string expression, ')' ={create_function(MYPEEK);}
+
+(double) const
+ -> number:n =n;
+ -> '+', number:n =n;
+ -> '-', number:n =-n;
+
+/*
+number
+ -> FNUM ={$$=$1;}
+ -> DIGITS ={$$=atoi($1);}
+*/
+
+(int) intnum
+ -> DIGITS:d                            =atoi(d);
+
+(char *) symbol_or_lineno
+ -> DIGITS:s =s;
+ -> SYMBOL:s =s;
+
+dimlist
+ -> SYMBOL:s, '(', !{
+pushcounter();},
+   indexlist, ')' ={create_dim(s,'d');}
+ -> dimlist, ',', SYMBOL:s, '(', !{
+pushcounter();},
+   indexlist, ')' ={create_dim(s,'d');}
+ -> STRSYM:s, '(', !{
+pushcounter();},
+   indexlist, ')' ={create_dim(s,'s');}
+ -> dimlist, ',', STRSYM:s, '(', !{
+pushcounter();},
+   indexlist, ')' ={create_dim(s,'s');}
+
+indexlist
+ -> expression ={inccounter();}
+ -> indexlist, ',', expression ={inccounter();}
+
+for_loop
+ -> "FOR", SYMBOL:s, '=', expression, !{
+pushname(s);create_popdblsym(s);pushgoto();
+             create_pushdblsym(s);},
+   "TO", expression, step_part:p, !{
+
+       create_dblrelop((p>0)?'{':'}');
+             create_decide();
+             pushlabel();},
+/*
+   SEP, !{
+yylineno+=$10;},
+*/ SEP,
+   statement list, !{
+             create_pushdbl(p);
+       create_pushdblsym(s);
+             create_dblbin('+');
+       create_popdblsym(s);
+             swap();popgoto();poplabel();},
+   next_or_eofile, next_symbol                    ={/* cookie*/}
+
+next_or_eofile
+ -> "NEXT"
+ -> eof ={end_of_file=TRUE;
+      error(ERROR,"'next'-statement is missing"); PCB.exit_flag = AG_SYNTAX_ERROR_CODE;}
+
+(double) step_part
+ ->  /* can be omitted */ =1.0;
+ -> "STEP", const:v =v;
+
+next_symbol
+ -> /* can be omitted */ ={pop();}
+ -> SYMBOL:s ={if (strcmp(pop()->pointer,s))
+             {error(ERROR,"'for' and 'next' do not match"); PCB.exit_flag = AG_SYNTAX_ERROR_CODE;}
+           }
+
+if_clause
+ -> "IF", condition, !{
+create_decide();pushlabel();},
+   "THEN", statement list, !{
+pushlabel();swap();poplabel();},
+   else_part, !{
+poplabel();},
+   endif_or_eof
+
+endif_or_eof
+ -> "ENDIF"
+ -> eof ={end_of_file=TRUE;
+            error(ERROR,"'endif'-statement is missing"); PCB.exit_flag = AG_SYNTAX_ERROR_CODE;}
+/*
+condition
+ -> '(', condition, ')'
+ -> condition, "OR", condition ={create_boole('|');}
+ -> "NOT", condition ={create_boole('!');}
+*/
+
+condition
+ -> and condition
+ -> condition, "OR", and condition ={create_boole('|');}
+
+
+and condition
+ -> primary condition
+ -> and condition, "AND", primary condition ={create_boole('&');}
+
+primary condition
+ -> comparison
+ -> '(', condition, ')'
+ -> "NOT", primary condition
+
+comparison
+ -> string expression, '=', string expression ={create_strrelop('=');}
+ -> string expression, "<>", string expression ={create_strrelop('!');}
+ -> string expression, '<', string expression ={create_strrelop('<');}
+ -> string expression, "<=", string expression ={create_strrelop('{');}
+ -> string expression, '>', string expression ={create_strrelop('>');}
+ -> string expression, ">=", string expression ={create_strrelop('}');}
+ -> expression, '=', expression ={create_dblrelop('=');}
+ -> expression, "<>", expression ={create_dblrelop('!');}
+ -> expression, '<', expression ={create_dblrelop('<');}
+ -> expression, "<=", expression ={create_dblrelop('{');}
+ -> expression, '>', expression ={create_dblrelop('>');}
+ -> expression, ">=", expression ={create_dblrelop('}');}
+ //-> MYEOF, '(', hashed_number, ')' ={create_testeof($3);}
+
+else_part /* can be omitted */
+ ->
+ -> "ELSE", statement list
+
+inputlist
+ -> input
+ -> input, ',', inputlist
+
+input
+ -> SYMBOL:s ={create_myread('d');create_popdblsym(s);}
+ -> SYMBOL:s, '(', !{
+pushcounter();},
+   indexlist, ')' ={create_myread('d');create_doarray(s,ASSIGNARRAY);}
+ -> STRSYM:s ={create_myread('s');create_popstrsym(s);}
+ -> STRSYM:s, '(', !{
+pushcounter();},
+   indexlist, ')' ={create_myread('s');create_doarray(s,ASSIGNSTRINGARRAY);}
+
+readlist
+ -> readitem
+ -> readlist, ',', readitem
+
+readitem
+ -> SYMBOL:s ={create_readdata('d');create_popdblsym(s);}
+ -> SYMBOL:s, '(', !{
+pushcounter();},
+   indexlist, ')' ={create_readdata('d');create_doarray(s,ASSIGNARRAY);}
+ -> STRSYM:s ={create_readdata('s');create_popstrsym(s);}
+ -> STRSYM:s, '(', !{
+pushcounter();},
+   indexlist, ')' ={create_readdata('s');create_doarray(s,ASSIGNSTRINGARRAY);}
+
+datalist
+ -> STRING:s ={create_strdata(s);}
+ -> const:v ={create_dbldata(v);}
+ -> datalist, ',', STRING:s ={create_strdata(s);}
+ -> datalist, ',', const:v ={create_dbldata(v);}
+
+printlist  /* possible empty */
+ ->
+ -> expression ={create_print('d');}
+ -> printlist, ',', expression ={create_print('d');}
+ -> string expression ={create_print('s');}
+ -> printlist, ',', string expression ={create_print('s');}
+
+inputintro
+ ->  ={create_myswitch(0);create_readline(NULL);}
+ -> stream
+ -> position ={create_myswitch(0);create_readline(NULL);}
+ -> !{
+create_myswitch(0);},
+   prompt
+ -> position, !{
+create_myswitch(0);},
+   prompt
+
+printintro
+ ->  /* can be empty */ ={create_myswitch(0);}
+ -> stream
+ -> "REVERSE" ={create_revert(TRUE);create_myswitch(0);}
+ -> position ={create_myswitch(0);}
+ -> "REVERSE", position ={create_revert(TRUE);create_myswitch(0);}
+
+prompt
+ -> STRING:s ={create_readline(s);}
+
+position
+ -> "AT", '(', expression, ',', expression, ')' ={create_mymove();}
+
+stream
+ -> '#', intnum:n ={create_myswitch(n);}
+
+(int) hashed_number
+ -> '#', intnum:n =n;
+ -> intnum:n /* need not contain hash */ =n;
+
+semicolon /* can be left out */
+ ->  ={create_print('n');}
+ -> ';'
+
+goto_list
+ -> symbol_or_lineno:s ={create_goto(s);create_findnop();}
+ -> goto_list, ',', symbol_or_lineno:s ={create_goto(s);create_findnop();}
+
+gosub_list
+ -> symbol_or_lineno:s ={create_gosub(s);create_findnop();}
+ -> gosub_list, ',', symbol_or_lineno:s ={create_gosub(s);create_findnop();}
+
+{
+#define CHAR_STACK_LENGTH 500
+
+static char  charStack[CHAR_STACK_LENGTH+1];
+static char *charStackTop = charStack;
+
+/* Define an error record */
+typedef struct {
+  char *message;                 /* identifies error */
+  int line;                      /* location of error */
+  int column;
+} ErrorRecord;
+
+ErrorRecord errorRecord;           /* define an error record */
+
+void diagnoseError(char *msg) {
+  if (parseBasic_pcb.exit_flag == AG_RUNNING_CODE)
+    parseBasic_pcb.exit_flag = AG_SEMANTIC_ERROR_CODE;      /* stop parse */
+  errorRecord.message = msg;
+  errorRecord.line    = parseBasic_pcb.line;
+  errorRecord.column  = parseBasic_pcb.column;
+}
+
+void pushChar(int c) {              /* append char to name string */
+  if (charStackTop < charStack+CHAR_STACK_LENGTH) {
+    *charStackTop++ = (char) c;
+    return;
+  }
+  /* buffer overflow, kill parse and issue diagnostic */
+  diagnoseError("Character Stack Overflow");
+}
+
+static char *popString(int nChars) {                /* get string */
+  *charStackTop = 0;
+  return charStackTop -= nChars;
+}
+
+FILE *parserInputFile;
+void switch_to_my_file(FILE *inputfile) /* switches lex input to given file */
+{
+  parserInputFile = inputfile;
+  return;
+}
+
+#define GET_INPUT ((PCB).input_code = fgetc(parserInputFile))
+
+int yyparse() {
+  parseBasic();
+  return !(PCB.exit_flag == AG_SUCCESS_CODE);
+}
+
+
+}