搜索 社区服务 统计排行 帮助
  • 1482阅读
  • 4回复

请问大家:如何写一个控制脚本?

楼层直达
级别: 新手上路
注册时间:
2008-07-10
在线时间:
0小时
发帖:
16
大家谁可以给点帮助,或者弄一个简单的例子。
谢谢了

never give up
级别: 精灵王
注册时间:
2008-04-08
在线时间:
44小时
发帖:
2855
只看该作者 1楼 发表于: 2008-10-22
什么脚本?控制什么?
级别: 新手上路
注册时间:
2008-07-10
在线时间:
0小时
发帖:
16
只看该作者 2楼 发表于: 2008-10-22
比如 :RGB(OutWidth=AUTO, OutHeight=360,INBUF=buff0)

如何实现这样的RGB呢?

never give up
级别: 新手上路
注册时间:
2008-07-10
在线时间:
0小时
发帖:
16
只看该作者 3楼 发表于: 2008-10-22
// TinyBASIC.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include
#include
#include
#include
#include

#define NUM_LAB100
#define LAB_LEN10
#define FOR_NEST25
#define SUB_NEST25
#define PROG_SIZE10000

#define DELIMITER1
#define VARIABLE2
#define NUMBER3
#define COMMAND4
#define STRING5
#define QUOTE6

#define PRINT1
#define INPUT2
#define IF3
#define THEN4
#define FOR5
#define NEXT6
#define TO7
#define GOTO8
#define EOL9
#define FINISHED10
#define GOSUB11
#define RETURN12
#define END13

// Holds expressions to be analyzed.
char* prog;

// Holds environment for longjmp().
jmp_buf e_buf;

// 26 user variables,A-Z.
int variables[ 26 ] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };

// Keywords lookup table.Commands must be entered lowercase in this table.
struct commands {
char command[ 20 ];
char tok;
} table[] = {
{ "print", PRINT },
{ "input", INPUT },
{ "if",IF },
{ "then", THEN },
{ "goto", GOTO },
{ "for", FOR},
{ "next", NEXT },
{ "to",TO },
{ "gosub", GOSUB },
{ "return",RETURN },
{ "end", END},
{ "", END}
};

char token[ 80 ];
char token_type;
char tok;

struct label {
char name[ LAB_LEN ];
char* p;// Points to place to go in source file.
} label_table[ NUM_LAB ];

char* find_label();
char* gpop();

// Stack for FOR-NEXT loop.
struct for_stack {
int var;// Counter variable.
int target;// Target value.
char* loc;
} fstack[ FOR_NEST ];

struct for_stack fpop();

// Stack for GOSUB.
char* gstack[ SUB_NEST ];

// Index to top of FOR stack.
int ftos;

// Index to top of GOSUB stack.
int gtos;

void print();
void scan_labels();
void find_eol();
void exec_goto();
void exec_if();
void exec_for();
void exec_next();
void input();
void gosub();
void greturn();

int load_program( char* p,char* fname );
void label_init();
int get_next_label( char* s );
void fpush( struct for_stack i );
void gpush( char* s );
int look_up( char* s );

void get_exp( int* result );
//void level1( int* result );
void assignment();
void level2( int* result );
void level3( int* result );
void level4( int* result );
void level5( int* result );
void level6( int* result );
void primitive( int* result );
void arith( char o,int* r,int* h );
void unary( char o,int* r );
void putback();
void serror( int error );
void get_token();
int iswhite( char c );
int isdelim( char c );
int find_var( char* s );

int _tmain(int argc, _TCHAR* argv[])
{
char* p_buf;

if (argc != 2)
{
printf("Usage: TinyBasic \r\n");
exit(1);
}

// Allocate memory for the program.
if (!(p_buf = (char*)malloc(PROG_SIZE)))
{
printf("Allocate memory failure!\r\n");
exit(1);
}

// Load the program to execute.
if (!load_program(p_buf,argv[1]))
{
free(p_buf);
printf("Can not load the program %s to execute!\r\n",argv[1]);
exit(1);
}

// Initialize the long jump buffer.
if (setjmp(e_buf))
{
free(p_buf);
printf("Can not set long jump!\r\n");
exit(1);
}

prog = p_buf;
scan_labels();
ftos = 0;
gtos = 0;

do
{
//token_type = get_token();
get_token();

// Check for assignment statement.
if(token_type == VARIABLE)
{
putback();// Return the variable to the input stream.
assignment();// Must be assignment statement.
}
// Is command.
else
{
switch(tok)
{
case PRINT:
print();
break;
case GOTO:
exec_goto();
break;
case IF:
exec_if();
break;
case FOR:
exec_for();
break;
case NEXT:
exec_next();
break;
case INPUT:
input();
break;
case GOSUB:
gosub();
break;
case RETURN:
greturn();
break;
case END:
exit(0);
}
}
} while(tok != FINISHED);

free(p_buf);

return 0;
}

int load_program(char* p,char* fname)
{
FILE* fp;
int i;

if(!(fp = fopen(fname,"rb")))
return 0;

i = 0;
do
{
*p = getc(fp);
p++;
i++;
} while(!feof(fp) && i < PROG_SIZE);
*(p - 2) = '\0';// Null terminate the program.

fclose(fp);

return 1;
}

void assignment()
{
int var;
int value;

// Get the variable name.
get_token();
if(!isalpha(*token))
{
serror(4);
return;
}

var = toupper(*token) - 'A';
if(*token != '=')
{
serror(3);
return;
}

// Get the value to assign to variable.
get_exp(&value);
variables[var] = value;
}

// Execute a simple version of the BASIC "PRINT" statement.
void print()
{
int answer;
int len = 0;
int spaces;
char last_delim;

do
{
get_token();// Get next list item.
if ( tok == EOL || tok == FINISHED )
break;
if (token_type == QUOTE)
{// Is String.
printf(token);
len += (int)strlen( token );
get_token();
}
else
{// Is expression.
putback();
get_exp(&answer);
get_token();
len += printf("%d",answer);
}
last_delim = *token;

if (*token == ';')
{
// Compute number of sapces to move to next TAB.
spaces = 8 - (len % 8);
// Add in the tabbing position.
len += spaces;
while(spaces)
{
printf(" ");
spaces --;
}
}
else if(*token == ',')
{
// Do nothing.
}
else if(tok != EOL && tok != FINISHED)
{
serror(0);
}
} while(*token == ';' || *token == ',');

if(tok == EOL || tok == FINISHED)
{
if(last_delim != ';' && last_delim != ',')
printf("\n");
}
else
{
serror(0);
}
}

// Find all labels.
void scan_labels()
{
int addr;
char* temp;

// Zero all labels.
label_init();
// Save pointer to top of program.
temp = prog;

// If the first token in the file is label.
get_token();
if(token_type == NUMBER)
{
strcpy(label_table[0].name,token);
label_table[0].p = prog;
}

find_eol();
do
{
get_token();
if(token_type == NUMBER)
{
addr = get_next_label(token);
if(addr == -1 || addr == -2)
{
addr == -1 ? serror(5) : serror(6);
}
strcpy(label_table[addr].name,token);
label_table[addr].p = prog;
}
// If not on a blank line,find next line.
if(tok != EOL)
find_eol();
} while(tok != FINISHED);

prog = temp;
}

// Find the start of the next line.
void find_eol()
{
while(*prog != '\n' && *prog != '\0')
++prog;
if(*prog)
prog++;
}

// Return index of next free position in label arrary.
// -1: is returned if the array is full;
// -2: is returned when duplicate label is found.
int get_next_label(char* s)
{
int t;

for(t = 0; t < NUM_LAB; ++t)
{
if(label_table[t].name[0] == 0)
return t;
if(!strcmp(label_table[t].name,s))
return -2;
}
return -1;
}

// Find location of given label.A null is returned if label is not found;otherwise a pointer to
// the position of label is returned.
char* find_label(char* s)
{
int t;

for(t = 0; t < NUM_LAB; ++t)
{
if(!strcmp(label_table[t].name,s))
return label_table[t].p;
}
return 0;
}

// Execute a GOTO command.
void exec_goto()
{
char* loc;
// Get label to goto.
get_token();
// Find the location of label.
loc = find_label(token);
if(loc == '\0')
serror(7);// Label not define.
else
prog = loc;// Start program running at that loc.
}

// Initilize the array that holds the labels.
// By convention,a null label name indicates that array position is unused.
void label_init()
{
int t;
for(t = 0; t < NUM_LAB; ++t)
label_table[t].name[0] = '\0';
}

// Execute an IF statement.
void exec_if()
{
int x;
int y;
int cond;
char op;

get_exp(&x);// Get left expression.

get_token();// Get the operator.
if(!strchr("=<>",*token))
{
serror(0);
return;
}
op = *token;

get_exp(&y);// Get the right expression.

// Determine the outcome.
cond = 0;
switch( op )
{
case '<':
if(x < y)
cond = 1;
break;
case '>':
if(x > y)
cond = 1;
break;
case '=':
if(x == y)
cond = 1;
break;
}

if(cond)
{// Is true so process target of IF.
get_token();
if(tok != THEN)
{
serror(8);
return;
}// else program execution starts on next line.
}
else
find_eol();// Find start of next line.
}

// Execute a FOR loop.
void exec_for()
{
struct for_stack i;
int value;

get_token();// Read the control variable.
if(!isalpha(*token))
{
serror(4);
return;
}
i.var = toupper(*token) - 'A';// Save its index.

get_token();// Read the equals sign.
if(*token != '=')
{
serror(3);
return;
}

get_exp(&value);// Get initial value.
variables[i.var] = value;

get_token();
if(tok != TO)
serror(9);// Read and discard the TO.

get_exp(&i.target);// Get target value.

// If loop can execute at least once,push info on stack.
if(value >= variables[i.var])
{
i.loc = prog;
fpush(i);
}
else// Otherwise,skip loop code altogether.
{
while(tok != NEXT)
get_token();
}
}

// Execute a NEXT statement.
void exec_next()
{
struct for_stack i;

i = fpop();// Read the loop info.

variables[i.var]++;// Increment control variable.
if(variables[i.var] > i.target)
return;// All down.
fpush(i);

prog = i.loc;// Loop.
}

// Push function for the FOR stack.
void fpush(struct for_stack i)
{
if(ftos > FOR_NEST)
serror( 0 );
fstack[ftos] = i;
ftos++;
}

// Pop function for the FOR stack.
struct for_stack fpop()
{
ftos--;
if(ftos < 0)
serror(11);
return(fstack[ftos]);
}

// Execute a simple form of the BASIC INPUT command.
void input()
{
char var;
int i;

get_token();// See if prompt string is present.
if(token_type == QUOTE)
{
printf(token);
// If so,print it and check for comma.
get_token();
if(*token != ',')
serror(1);
get_token();
}
else printf("?");// Otherwise,prompt with "?".

var = toupper(*token) - 'A';// Get the input variable.
scanf("%d", &i);// Read input.

variables[var] = i;// Store it.
}

// Execute a GOSUB statement.
void gosub()
{
char* loc;

get_token();
// Find the label to call.
loc = find_label(token);
if(loc == '\0')
{
serror( 7 );
}
else
{
gpush( prog );// Save place to return to.
prog = loc;// Start program running at that loc.
}
}

// Return from GOSUB.
void greturn()
{
prog = gpop();
}

// GOSUB stack push fuction.
void gpush(char* s)
{
gtos++;
if (gtos == SUB_NEST)
{
serror(12);
return;
}

gstack[gtos] = s;
}

// GOSUB stack pop function.
char* gpop()
{
if(gtos == 0)
{
serror(13);
return 0;
}

return gstack[gtos--];
}

void get_exp(int* result)
{
get_token();
if(!(*token))
{
serror(2);
return;
}
level2(result);
putback();// Retuen last token read to input string.
}

void level2(int* result)
{
char op;
int hold;

level3(result);
while ((op = *token) == '+' || op == '-')
{
get_token();
level3(&hold);
arith(op,result,&hold);
}
}

void level3(int* result)
{
char op;
int hold;

level4(result);
while ((op = *token) == '*' || op == '/' || op == '%')
{
get_token();
level4(&hold);
arith(op,result,&hold);
}
}

void level4(int* result)
{
int hold;
level5(result);
if (*token == '^')
{
get_token();
level4(&hold);
arith('^',result, &hold);
}
}

void level5(int* result)
{
char op;
op = 0;
if ((token_type == DELIMITER) && *token == '+' || *token == '-')
{
op = *token;
get_token();
}
level6(result);
if(op)
{
unary(op, result);
}
}

void level6(int* result)
{
if ((*token == '(') && (token_type == DELIMITER))
{
get_token();
level2(result);
if (*token != ')')
{
serror(1);
return;
}
get_token();
}
else
{
primitive(result);
}
}

void primitive(int* result)
{
switch(token_type)
{
case VARIABLE:
*result = find_var(token);
get_token();
return;
case NUMBER:
*result = atoi(token);
get_token();
return;
default:
serror( 0 );
}
}

void arith(char o,int* r,int* h)
{
int t;
int ex;

switch(o)
{
case '-':
*r = *r - *h;
break;
case '+':
*r = *r + *h;
break;
case '*':
*r = (*r) * (*h);
break;
case '/':
*r = (*r) / (*h);
break;
case '%':
t = (*r) / (*h);
*r = *r - (t * (*h));
break;
case '^':
ex = *r;
if (*h == 0)
{
*r = 1;
}
else
{
for(t = *h - 1; t > 0; --t)
{
*r = (*r) * ex;
}
}
break;
}
}

void unary(char o, int* r)
{
if(o == '-')
*r = -(*r);
}

void putback()
{
char* t;
t = token;
for(; *t; t++)
prog--;
}

void serror(int error)
{
static char* e[] =
{
"Error: Syntax error!\r\n",
"Error: unbalanced parentheses!\r\n",
"Error: No expression present!\r\n",
"Error: equals sign expected!\r\n",
"Error: not a variable!\r\n",
"Error: label table full!\r\n",
"Error: duplicate label!\r\n",
"Error: undefined label!\r\n",
"Error: THEN expected!\r\n",
"Error: TO expected!\r\n",
"Error: too many nested FOR loops\r\n",
"Error: NEXT without FOR!\r\n",
"Error: too many nested GOSUB\r\n",
"Error: RETURN without GOSUB!\r\n"
};

printf("%s", e[error]);
longjmp(e_buf, 1);// Return to save point.
}

void get_token()
{
char* temp;

token_type = 0;
tok = 0;
temp = token;

if (*prog == '\0')
{
*token = 0;
tok = FINISHED;
token_type = DELIMITER;
return;
}

// Skip over white space.
while (iswhite(*prog))
++prog;

if (*prog == '\r')
{// CrLf.
++prog;
++prog;
tok = EOL;
token[0] = '\r';
token[1] = '\n';
token[2] = '\0';
token_type = DELIMITER;
return;
}

if (strchr("+-*^/%=;(),><", *prog))
{// Delimiter.
*temp = *prog;
prog++;// Advance to next position.
temp++;
*temp = 0;
token_type = DELIMITER;
return;
}

if (*prog == '"')
{// Quoted string.
prog++;
while (*prog != '"' && *prog != '\r')
*temp++ = *prog++;
if (*prog == '\r')
serror(1);
prog++;
*temp = 0;
token_type = QUOTE;
return;
}

if (isdigit(*prog))
{// Number.
while(!isdelim(*prog))
*temp++ = *prog++;
*temp = 0;
token_type = NUMBER;
return;
}

if (isalpha(*prog))
{// Variable or command.
while (!isdelim(*prog))
*temp++ = *prog++;
token_type = STRING;
}
*temp = 0;

// See if a string is a command or a variable.
if (token_type == STRING)
{
tok = look_up(token);
if(!tok)
token_type = VARIABLE;
else
token_type = COMMAND;
}
}

// Look up a token's internal representation in the token table.
int look_up(char* s)
{
int i;
char* p;
p = s;
while (*p)
{
*p = tolower(*p);
p++;
}

for (i = 0; *table[ i ].command; i++)
{
if (!strcmp(table.command, s))
return table.tok;
}

return 0;
}

int iswhite(char c)
{
if (c == ' ' || c == 0x9)
return 1;
return 0;
}

int isdelim(char c)
{
if (strchr(";,+-< >/*%^=()", c) || c == 0x9 || c == '\r' || c == 0)
return 1;
return 0;
}

int find_var(char* s)
{
if (!isalpha(*s))
{
serror(4);
return 0;
}
return variables[toupper(*token) - 'A'];
}

never give up
级别: 精灵王
注册时间:
2008-04-08
在线时间:
44小时
发帖:
2855
只看该作者 4楼 发表于: 2008-10-22
手写编译器用的自动机很痛苦的,建议用工具,比如Parser Generator 2
快速回复

限150 字节
上一个 下一个