mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-08-01 02:36:23 -04:00
adding pegmarkdown support library.
git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5953 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
4413536926
commit
3be22536df
107 changed files with 20038 additions and 0 deletions
361
supportlibs/pegmarkdown/peg-0.1.9/examples/basic.leg
Normal file
361
supportlibs/pegmarkdown/peg-0.1.9/examples/basic.leg
Normal file
|
@ -0,0 +1,361 @@
|
|||
# A 'syntax-directed interpreter' (all execution is a side-effect of parsing).
|
||||
# Inspired by Dennis Allison's original Tiny BASIC grammar, circa 1975.
|
||||
#
|
||||
# Copyright (c) 2007 by Ian Piumarta
|
||||
# All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the 'Software'),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, provided that the above copyright notice(s) and this
|
||||
# permission notice appear in all copies of the Software. Acknowledgement
|
||||
# of the use of this Software in supporting documentation would be
|
||||
# appreciated but is not required.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED 'AS IS'. USE ENTIRELY AT YOUR OWN RISK.
|
||||
#
|
||||
# Last edited: 2012-04-29 15:14:06 by piumarta on emilia
|
||||
|
||||
%{
|
||||
# include <stdio.h>
|
||||
|
||||
typedef struct line line;
|
||||
|
||||
struct line
|
||||
{
|
||||
int number;
|
||||
int length;
|
||||
char *text;
|
||||
};
|
||||
|
||||
line *lines= 0;
|
||||
int numLines= 0;
|
||||
int pc= -1, epc= -1;
|
||||
int batch= 0;
|
||||
|
||||
int nextline(char *buf, int max);
|
||||
|
||||
# define min(x, y) ((x) < (y) ? (x) : (y))
|
||||
|
||||
# define YY_INPUT(buf, result, max_size) \
|
||||
{ \
|
||||
if ((pc >= 0) && (pc < numLines)) \
|
||||
{ \
|
||||
line *linep= lines+pc++; \
|
||||
result= min(max_size, linep->length); \
|
||||
memcpy(buf, linep->text, result); \
|
||||
} \
|
||||
else \
|
||||
result= nextline(buf, max_size); \
|
||||
}
|
||||
|
||||
union value {
|
||||
int number;
|
||||
char *string;
|
||||
int (*binop)(int lhs, int rhs);
|
||||
};
|
||||
|
||||
# define YYSTYPE union value
|
||||
|
||||
int variables[26];
|
||||
|
||||
void accept(int number, char *line);
|
||||
|
||||
void save(char *name);
|
||||
void load(char *name);
|
||||
void type(char *name);
|
||||
|
||||
int lessThan(int lhs, int rhs) { return lhs < rhs; }
|
||||
int lessEqual(int lhs, int rhs) { return lhs <= rhs; }
|
||||
int notEqual(int lhs, int rhs) { return lhs != rhs; }
|
||||
int equalTo(int lhs, int rhs) { return lhs == rhs; }
|
||||
int greaterEqual(int lhs, int rhs) { return lhs >= rhs; }
|
||||
int greaterThan(int lhs, int rhs) { return lhs > rhs; }
|
||||
|
||||
int input(void);
|
||||
|
||||
int stack[1024], sp= 0;
|
||||
|
||||
char *help;
|
||||
|
||||
void error(char *fmt, ...);
|
||||
int findLine(int n, int create);
|
||||
%}
|
||||
|
||||
line = - s:statement CR
|
||||
| - n:number < ( !CR . )* CR > { accept(n.number, yytext); }
|
||||
| - CR
|
||||
| - < ( !CR . )* CR > { epc= pc; error("syntax error"); }
|
||||
| - !. { exit(0); }
|
||||
|
||||
statement = 'print'- expr-list
|
||||
| 'if'- e1:expression r:relop e2:expression { if (!r.binop(e1.number, e2.number)) yythunkpos= 0; }
|
||||
'then'- statement
|
||||
| 'goto'- e:expression { epc= pc; if ((pc= findLine(e.number, 0)) < 0) error("no such line"); }
|
||||
| 'input'- var-list
|
||||
| 'let'- v:var EQUAL e:expression { variables[v.number]= e.number; }
|
||||
| 'gosub'- e:expression { epc= pc; if (sp < 1024) stack[sp++]= pc, pc= findLine(e.number, 0); else error("too many gosubs");
|
||||
if (pc < 0) error("no such line"); }
|
||||
| 'return'- { epc= pc; if ((pc= sp ? stack[--sp] : -1) < 0) error("no gosub"); }
|
||||
| 'clear'- { while (numLines) accept(lines->number, "\n"); }
|
||||
| 'list'- { int i; for (i= 0; i < numLines; ++i) printf("%5d %s", lines[i].number, lines[i].text); }
|
||||
| 'run'- s:string { load(s.string); pc= 0; }
|
||||
| 'run'- { pc= 0; }
|
||||
| 'end'- { pc= -1; if (batch) exit(0); }
|
||||
| 'rem'- ( !CR . )*
|
||||
| ('bye'|'quit'|'exit')- { exit(0); }
|
||||
| 'save'- s:string { save(s.string); }
|
||||
| 'load'- s:string { load(s.string); }
|
||||
| 'type'- s:string { type(s.string); }
|
||||
| 'dir'- { system("ls *.bas"); }
|
||||
| 'help'- { fprintf(stderr, "%s", help); }
|
||||
|
||||
expr-list = ( e:string { printf("%s", e.string); }
|
||||
| e:expression { printf("%d", e.number); }
|
||||
)? ( COMMA ( e:string { printf("%s", e.string); }
|
||||
| e:expression { printf("%d", e.number); }
|
||||
)
|
||||
)* ( COMMA
|
||||
| !COMMA { printf("\n"); }
|
||||
)
|
||||
|
||||
var-list = v:var { variables[v.number]= input(); }
|
||||
( COMMA v:var { variables[v.number]= input(); }
|
||||
)*
|
||||
|
||||
expression = ( PLUS? l:term
|
||||
| MINUS l:term { l.number = -l.number }
|
||||
) ( PLUS r:term { l.number += r.number }
|
||||
| MINUS r:term { l.number -= r.number }
|
||||
)* { $$.number = l.number }
|
||||
|
||||
term = l:factor ( STAR r:factor { l.number *= r.number }
|
||||
| SLASH r:factor { l.number /= r.number }
|
||||
)* { $$.number = l.number }
|
||||
|
||||
factor = v:var { $$.number = variables[v.number] }
|
||||
| n:number
|
||||
| OPEN expression CLOSE
|
||||
|
||||
var = < [a-z] > - { $$.number = yytext[0] - 'a' }
|
||||
|
||||
number = < digit+ > - { $$.number = atoi(yytext); }
|
||||
|
||||
digit = [0-9]
|
||||
|
||||
string = '"' < [^\"]* > '"' - { $$.string = yytext; }
|
||||
|
||||
relop = '<=' - { $$.binop= lessEqual; }
|
||||
| '<>' - { $$.binop= notEqual; }
|
||||
| '<' - { $$.binop= lessThan; }
|
||||
| '>=' - { $$.binop= greaterEqual; }
|
||||
| '>' - { $$.binop= greaterThan; }
|
||||
| '=' - { $$.binop= equalTo; }
|
||||
|
||||
EQUAL = '=' - CLOSE = ')' - OPEN = '(' -
|
||||
SLASH = '/' - STAR = '*' - MINUS = '-' -
|
||||
PLUS = '+' - COMMA = ',' -
|
||||
|
||||
- = [ \t]*
|
||||
|
||||
CR = '\n' | '\r' | '\r\n'
|
||||
|
||||
%%
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
char *help=
|
||||
"print <num>|<string> [, <num>|<string> ...] [,]\n"
|
||||
"if <expr> <|<=|<>|=|>=|> <expr> then <stmt>\n"
|
||||
"input <var> [, <var> ...] let <var> = <expr>\n"
|
||||
"goto <expr> gosub <expr>\n"
|
||||
"end return\n"
|
||||
"list clear\n"
|
||||
"run [\"filename\"] rem <comment...>\n"
|
||||
"dir type \"filename\"\n"
|
||||
"save \"filename\" load \"filename\"\n"
|
||||
"bye|quit|exit help\n"
|
||||
;
|
||||
|
||||
void error(char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
if (epc > 0)
|
||||
fprintf(stderr, "\nline %d: %s", lines[epc-1].number, lines[epc-1].text);
|
||||
else
|
||||
fprintf(stderr, "\n");
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fprintf(stderr, "\n");
|
||||
va_end(ap);
|
||||
epc= pc= -1;
|
||||
}
|
||||
|
||||
#ifdef USE_READLINE
|
||||
# include <readline/readline.h>
|
||||
# include <readline/history.h>
|
||||
#endif
|
||||
|
||||
int nextline(char *buf, int max)
|
||||
{
|
||||
pc= -1;
|
||||
if (batch) exit(0);
|
||||
if (isatty(fileno(stdin)))
|
||||
{
|
||||
# ifdef USE_READLINE
|
||||
char *line= readline(">");
|
||||
if (line)
|
||||
{
|
||||
int len= strlen(line);
|
||||
if (len >= max) len= max - 1;
|
||||
strncpy(buf, line, len);
|
||||
(buf)[len]= '\n';
|
||||
add_history(line);
|
||||
free(line);
|
||||
return len + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
# endif
|
||||
putchar('>');
|
||||
fflush(stdout);
|
||||
}
|
||||
return fgets(buf, max, stdin) ? strlen(buf) : 0;
|
||||
}
|
||||
|
||||
int maxLines= 0;
|
||||
|
||||
int findLine(int n, int create)
|
||||
{
|
||||
int lo= 0, hi= numLines - 1;
|
||||
while (lo <= hi)
|
||||
{
|
||||
int mid= (lo + hi) / 2, lno= lines[mid].number;
|
||||
if (lno > n)
|
||||
hi= mid - 1;
|
||||
else if (lno < n)
|
||||
lo= mid + 1;
|
||||
else
|
||||
return mid;
|
||||
}
|
||||
if (create)
|
||||
{
|
||||
if (numLines == maxLines)
|
||||
{
|
||||
maxLines *= 2;
|
||||
lines= realloc(lines, sizeof(line) * maxLines);
|
||||
}
|
||||
if (lo < numLines)
|
||||
memmove(lines + lo + 1, lines + lo, sizeof(line) * (numLines - lo));
|
||||
++numLines;
|
||||
lines[lo].number= n;
|
||||
lines[lo].text= 0;
|
||||
return lo;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void accept(int n, char *s)
|
||||
{
|
||||
if (s[0] < 32) /* delete */
|
||||
{
|
||||
int lno= findLine(n, 0);
|
||||
if (lno >= 0)
|
||||
{
|
||||
if (lno < numLines - 1)
|
||||
memmove(lines + lno, lines + lno + 1, sizeof(line) * (numLines - lno - 1));
|
||||
--numLines;
|
||||
}
|
||||
}
|
||||
else /* insert */
|
||||
{
|
||||
int lno= findLine(n, 1);
|
||||
if (lines[lno].text) free(lines[lno].text);
|
||||
lines[lno].length= strlen(s);
|
||||
lines[lno].text= strdup(s);
|
||||
}
|
||||
}
|
||||
|
||||
char *extend(char *name)
|
||||
{
|
||||
static char path[1024];
|
||||
int len= strlen(name);
|
||||
sprintf(path, "%s%s", name, (((len > 4) && !strcasecmp(".bas", name + len - 4)) ? "" : ".bas"));
|
||||
return path;
|
||||
}
|
||||
|
||||
void save(char *name)
|
||||
{
|
||||
FILE *f= fopen(name= extend(name), "w");
|
||||
if (!f)
|
||||
perror(name);
|
||||
else
|
||||
{
|
||||
int i;
|
||||
for (i= 0; i < numLines; ++i)
|
||||
fprintf(f, "%d %s", lines[i].number, lines[i].text);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
void load(char *name)
|
||||
{
|
||||
FILE *f= fopen(name= extend(name), "r");
|
||||
if (!f)
|
||||
perror(name);
|
||||
else
|
||||
{
|
||||
int lineNumber;
|
||||
char lineText[1024];
|
||||
while ((1 == fscanf(f, " %d ", &lineNumber)) && fgets(lineText, sizeof(lineText), f))
|
||||
accept(lineNumber, lineText);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
void type(char *name)
|
||||
{
|
||||
FILE *f= fopen(name= extend(name), "r");
|
||||
if (!f)
|
||||
perror(name);
|
||||
else
|
||||
{
|
||||
int c, d;
|
||||
while ((c= getc(f)) >= 0)
|
||||
putchar(d= c);
|
||||
fclose(f);
|
||||
if ('\n' != d && '\r' != d) putchar('\n');
|
||||
}
|
||||
}
|
||||
|
||||
int input(void)
|
||||
{
|
||||
char line[32];
|
||||
fgets(line, sizeof(line), stdin);
|
||||
return atoi(line);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
lines= malloc(sizeof(line) * (maxLines= 32));
|
||||
numLines= 0;
|
||||
|
||||
if (argc > 1)
|
||||
{
|
||||
batch= 1;
|
||||
while (argc-- > 1)
|
||||
load(*++argv);
|
||||
pc= 0;
|
||||
}
|
||||
|
||||
while (!feof(stdin))
|
||||
yyparse();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue