BrainF**k的编译器
按照语法编写了这个“编译器”(对于解释性语言而言“编译”二字的确很奇怪)。
功能:
1.“编译”、运行一个后缀为 '.bf' 的文件;
2.提供错误指示,目前包括 RE 和 CE ;
3.提供 'help' 的指令帮助;
4.提供文件打开的功能(使用 Windows 下的记事本,所以本程序是仅限 Windows 使用的......);
源码:
#include <conio.h>
#include <windows.h>
#include <bits/stdc++.h>
using namespace std;
typedef bool ( * Functions )();
typedef pair<int, int> pii;
const char *LoadingBar[11] =
{
" ",
"- ",
"-- ",
"--- ",
"---- ",
"----- ",
"------ ",
"------- ",
"-------- ",
"--------- ",
"----------" };
const int MAXN = 1e6 + 5;
pii pos[MAXN];
int stk[MAXN], cp[MAXN], top;
int val[MAXN] = {}, ed[MAXN];
char code[MAXN], buf[MAXN];
int len, cnt;
namespace Error
{
void PrintPosition( const int cur, char ptr )
{
int r = pos[cur].first;
int beg = ed[r - 1] + 1, eed = ed[r];
for( int i = max( beg, cur - 3 ) ; i <= min( eed, cur + 3 ) ; i ++ ) putchar( code[i] );
putchar( '\n' ); for( int i = max( beg, cur - 3 ) ; i < cur ; i ++ ) putchar( ' ' );
putchar( ptr ), putchar( '\n' );
}
void RE( const int cur )
{
printf( "Runtime error on: Line %d, Character %d.\n", pos[cur].first, pos[cur].second );
printf( "Error: out of memory.\n" );
PrintPosition( cur, 'x' ), putchar( '\n' );
}
void CE( const int cur, bool type )
{
printf( "Compilation error on: Line %d, Character %d.\n", pos[cur].first, pos[cur].second );
printf( "Mismatched %s bracket.\n", type ? "right" : "left" );
PrintPosition( cur, '?' ), putchar( '\n' );
}
void UF()
{
puts( "Unknown file name." );
}
void UC()
{
puts( "Unknown command. Please put in \'help\' for help." );
}
void UnknownFormat()
{
puts( "Unknown format, please input \'help\' for help.\n" );
}
};
using namespace Error;
namespace Function
{
bool Compile()
{
bool flag; int lst = 0;
printf( "Processing: [%s]: 0%%\n", LoadingBar[0] );
for( int i = 1 ; i <= len ; i ++ )
{
if( code[i] == '[' ) stk[++ top] = i;
if( code[i] == ']' )
{
cp[i] = stk[top], cp[stk[top --]] = i;
if( top < 0 ) { CE( i, 1 ); return false; }
}
flag = false;
while( lst < 10 && lst + 1 < 10.0 * i / len ) flag = true, lst ++;
if( flag ) printf( "Processing: [%s]: %.1lf%%\n", LoadingBar[lst], 100.0 * i / len );
}
if( top ) { CE( stk[1], 0 ); return false; }
puts( "Done!\n" );
return true;
}
FILE* GetFile( string Name )
{
int L = Name.size(); len = cnt = 0;
for( int i = 0 ; i < L ; i ++ ) buf[i] = Name[i];
buf[L] = '.', buf[L + 1] = 'b', buf[L + 2] = 'f';
FILE *source = fopen( buf, "r" );
for( int i = 0 ; i < L + 5 ; i ++ ) buf[i] = '\0';
return source;
}
int GetCode( string Name )
{
FILE *source = GetFile( Name );
if( source == NULL ) { UF(), fclose( source ); return 0; }
while( ~ fscanf( source, "%s", buf + 1 ) )
{
cnt ++;
for( int i = 1 ; buf[i] && buf[i] != '\r' && buf[i] != '\n' ; i ++ )
code[++ len] = buf[i], pos[len] = pii( cnt, i );
for( int i = 1 ; buf[i] ; i ++ ) buf[i] = '\0';
ed[cnt] = len;
}
fclose( source );
return 1;
}
bool CheckOrder( string A, string B )
{
if( A.length() < B.length() ) return false;
for( int i = 0 ; i < B.length() ; i ++ )
if( A[i] != B[i] ) return false;
return true;
}
};
using namespace Function;
struct Interface
{
public :
int act();
};
struct Basic : public Interface
{
private :
bool Help()
{
puts(
"Command - Use\n\
help Show the usable commands.\n\
quit Quit the program.\n\
exit Exactly the same as command \"quit\".\n\
run Compile and run a file with suffix \".bf\".\n\
Format:\n\
run [File Name]\n\
open Open a file with suffix \".bf\".\n\
Format:\n\
open [File Name]\n\
clean Clean the screen.\n" );
return false;
}
bool Run()
{
puts( "Running..." );
Sleep( 300 );
int ptr = 0;
memset( val, 0, sizeof val );
clock_t start = clock();
for( int i = 1 ; i <= len ; i ++ )
{
if( code[i] == '>' ) { ptr ++; if( ptr == MAXN ) { RE( i ); return false; } }
else if( code[i] == '<' ) { ptr --; if( ptr < 0 ) { RE( i ); return false; } }
else if( code[i] == '+' ) val[ptr] ++;
else if( code[i] == '-' ) val[ptr] --;
else if( code[i] == '.' ) putchar( val[ptr] );
else if( code[i] == ',' ) val[ptr] = getchar();
else if( code[i] == '[' ) { if( val[ptr] == 0 ) i = cp[i]; }
else if( code[i] == ']' ) { if( val[ptr] ) i = cp[i]; }
}
clock_t ed = clock();
puts( "\n--------------------------------------------------" );
printf( "Run Time: %lfs\n\n", ( double ) ( ed - start ) / CLOCKS_PER_SEC );
return true;
}
void CompileAndRun( const string order )
{
string name;
stringstream ss( order );
ss >> name;
if( ! ( ss >> name ) ) { UnknownFormat(); return ; }
if( ss >> name ) { UnknownFormat(); return ; }
if( ! GetCode( name ) ) return ;
if( Compile() ) Run();
}
void OpenFile( const string order )
{
string name;
stringstream ss( order );
ss >> name;
if( ! ( ss >> name ) ) { UnknownFormat(); return ; }
if( ss >> name ) { UnknownFormat(); return ; }
FILE *source = GetFile( name );
if( source == NULL ) { UF(), fclose( source ); return ; }
fclose( source );
system( ( "notepad " + name + ".bf" ).c_str() );
}
public :
int act()
{
string comm;
while( true )
{
system( "cls" );
cout << "Brain Fuck Environment : Version : 1.1.0" << endl;
while( true )
{
cout << "BFE > ";
getline( cin, comm, '\n' );
if( comm == "debug" ) return 2;
else if( comm == "quit" || comm == "exit" ) goto quit;
else if( CheckOrder( comm, "run" ) ) CompileAndRun( comm );
else if( CheckOrder( comm, "open" ) ) OpenFile( comm );
else if( comm == "clean" ) break;
else if( comm == "help" ) Help();
else UC();
}
}
quit :
return 0;
}
}base;
struct Debuger : public Interface
{
private :
void Help()
{
puts(
"Command - Use\n\
help Show the usable Commands.\n\
quit Quit the debuger.\n\
exit Exactly the same as command \"quit\".\n" );
}
public :
int act()
{
string comm;
while( true )
{
system( "cls" );
cout << "Brain Fuck Environment :: Debuger : Version : 0.0.0" << endl;
while( true )
{
cout << "Debuger > ";
getline( cin, comm, '\n' );
if( CheckOrder( comm, "help" ) ) Help();
else if( CheckOrder( comm, "quit" ) ) goto quit;
else if( CheckOrder( comm, "exit" ) ) goto quit;
}
}
quit :
return 1;
}
}debug;
struct End : public Interface
{
public :
int act() { exit( 0 ); return 0; }
}finish;
int main()
{
system( "@echo off" );
int cur = 1;
while( true )
{
if( cur == 0 ) cur = finish.act();
if( cur == 1 ) cur = base.act();
if( cur == 2 ) cur = debug.act();
}
return 0;
}
BrainF**k的编译器的更多相关文章
- Brainf**k(一位数求max)
题目大意:给你两个一位数,要你求出其中的较大值(使用$Brainf**k$) ($Brainf**k$简介,相当于有一个数组和一个指针,","为把数组当前位赋值为读入的数,&quo ...
- BT雷人的程序语言
原文:http://cocre.com/?p=1142 酷壳 这个世界从来都不会缺少另类的东西,人类自然世界如此,计算机世界也一样.编程语言方面,看过本站<6个变态的C语言Hello Worl ...
- 6个变态的C语言Hello World程序 之 雷人的程序语言
以下的六个程序片段主要完毕这些事情: 输出Hello, World 混乱C语言的源码 以下的全部程序都能够在GCC下编译通过,仅仅有最后一个须要动用C++的编译器g++才干编程通过. hello1.c ...
- CTF中那些脑洞大开的加密(1)
0x01 目录 各种文本加密 Shell 1 2 3 4 5 6 7 8 9 10 11 12 换位加密: 1.栅栏密码(Rail-fence Cipher) ...
- c语言数据问题
变量都有作用域,链接属性,和存储类型3个属性,这三个属性决定了变量的作用域和生存期的问题 在c语言中包含4中类型, 整形 浮点型 指针 聚合类型(数组,结构体等) ------------------ ...
- CTF中那些脑洞大开的编码和加密
0x00 前言 正文开始之前先闲扯几句吧,玩CTF的小伙伴也许会遇到类似这样的问题:表哥,你知道这是什么加密吗?其实CTF中脑洞密码题(非现代加密方式)一般都是各种古典密码的变形,一般出题者会对密文进 ...
- 深入浅出C++引用(Reference)类型
要点1:为反复使用的.冗长的变量名称定义一个简短的.易用的别名,从而简化了代码.通常,冗长的变量名称源于多层嵌套对象,例如类中定义嵌套类,类中定义其它类对象. //------ 未使用引用的程序片段, ...
- Java的面向对象思想
多态性: 一种方法有多种实现,采用哪一种实现由Java虚拟机在运行时动态决定,这种能力成为动态绑定(dynamic binding),也称为多态性(polymorphism)(源于一个希腊单词,意为“ ...
- BZOI 1507 [NOI2003] Editor
Background After trying to solve problem EDIT1(Editor) and being ****ed by Brainf**k, Blue Mary deci ...
随机推荐
- Objective-C中的加号与减号
在Objective-C中,方法分为类方法和实例方法. 前置加号(+)的方法为类方法,这类方法是可以直接用类名来调用的,它的作用主要是创建一个实例.有人把它称为创建实例的工厂方法. 前置减号(-)的方 ...
- Git基本操作命令合集
平时自己敲敲代码,使用Git命令也渐渐多了起来.使用起来的确很方便,今天来分享下Git基本概念和本地代码提交到github上的过程,很简单的,多操作几次就会了. Git定义 Git 是一个开源的分布式 ...
- Poj2965 冰箱的开关
#include<iostream> using namespace std; int flag; int step; ][]; ] = { }; ] = { }; void turn(i ...
- [JavaWeb基础] 028.CSS简介和基础语法
css 概述 CSS 指层叠样式表 (Cascading Style Sheets) 样式定义如何显示 HTML 元素 样式通常存储在样式表中 把样式添加到 HTML 4.0 中,是为了解决内容与表现 ...
- DFA最小化
1.将DFA最小化:教材P65 第9题 2.构造以下文法相应的最小的DFA S→ 0A|1B A→ 1S|1 B→0S|0 3.自上而下语法分析,回溯产生的原因是什么? 文法中,对于某个非终结符号的规 ...
- Beta冲刺 —— 5.31
这个作业属于哪个课程 软件工程 这个作业要求在哪里 Beta冲刺 这个作业的目标 Beta冲刺 作业正文 正文 github链接 项目地址 其他参考文献 无 一.会议内容 1.讨论并解决每个人存在的问 ...
- Take advantage of Checkra1n to Jailbreak iDevice for App analysis
An unpatchable bootrom exploit called "checkm8" works on all iDevices up until the iPhone ...
- Java实现 LeetCode 429 N叉树的层序遍历
429. N叉树的层序遍历 给定一个 N 叉树,返回其节点值的层序遍历. (即从左到右,逐层遍历). 例如,给定一个 3叉树 : 返回其层序遍历: [ [1], [3,2,4], [5,6] ] 说明 ...
- Java实现 蓝桥杯VIP 算法训练 奇偶判断
问题描述 能被2整除的数称为偶数,不能被2整除的数称为奇数.给一个整数x,判断x是奇数还是偶数. 输入格式 输入包括一个整数x,0<=x<=100000000. 输出格式 如果x是奇数,则 ...
- Java实现 蓝桥杯VIP 算法提高 P0404
计算一个无符号整数的阿尔法乘积.对于一个无符号整数x来说,它的阿尔法乘积是这样来计算的:如果x是一个个位数,那么它的阿尔法乘积就是它本身:否则的话,x的阿尔法乘积就等于它的各位非0的数字相乘所得到的那 ...