之前想实现一个简单的C语言编译器,结果走错了方向,这个版本算是一个纪念吧,这个版本是if和else的语句都会执行,无论if里面的语句是否为true。
编译和执行命令为
flex *.l
bison -d *.y
g++ -o cal *.c -lfl
./cal
我写的程序支持的语句
变量定义,我只支持三种变量定义,一个是整型,一个是string,一个是布尔类型。
int cc =88 ; exit
bool cc =true ; exit
str cc =six ; exit
逻辑(实际上没有逻辑判断)
if t && t str cc =six ;print cc ;exit
if t && t str cc =six ;print cc else print cc ;exit
他们的任意混合
int cc = 99; int bb=88; if cc<=bb print cc else print bb ; exit
组合规则
两个语句(赋值语句、打印输出语句都是语句)之间用‘;’
if语句结束用‘;’
全部结束用exit
lexya_a_.l
%{
#include "stdio.h"
union data{
int n;
char* ch;
double f;
bool b;
};
#define YYSTYPE data
#include "lexya_a.tab.h"
extern "C" int yylex();
%}
%%
if {return IF;}
int {return INT;}
exit {return EXIT;}
print {return PRINT;}
str {return STRING;}
bool {return BOOL;}
ifx {return IFX;}
else {return ELSE;}
[-+*/=|&><;] {return *yytext;}
[tf] {if(*yytext=='t')yylval.b=true;else yylval.b=false;return TF;}
[0-9]+ { yylval.n = atoi(yytext); return NUMBER; }
[a-z][a-z0-9]* {yylval.ch = strdup(yytext);return STR; }
[\t] ; /* ignore white space */
[\n] return 0;
. ;
%%
lexya_a.y
%{
#include <stdio.h>
#include <iostream>
#include<map>
#include<string>
#include <vector>
using namespace std;
vector<int> v;
vector<string> s;
vector<bool> b;
map<string,int> m1;
map<string,string> m2;
void yyerror(const char *s);
int check(char* s);
void prints(char* s,int i);
extern "C" int yylex();
union data{
int n;
char* ch;
double f;
bool b;
};
#define YYSTYPE data
%}
%token TRUE FALSE IF INT NUMBER STR PRINT TF BOOL STRING EXIT ELSE
%left '+' '-' '=' '|' ';' '<' '>'
%left '*' '/' '&'
%nonassoc ELSE
%%
prog: over EXIT {cout<<"程序结束!"<<endl;}
| over ';' EXIT {cout<<"程序结束!"<<endl;}
over: over ';' over
| calculation
| prin
| IF exrp over ';'
| IF exrp over ELSE over ';'
exrp: exrp '|' '|' exrp {$$.b=$1.b||$4.b;}
| exrp '&' '&' exrp {$$.b=$1.b&&$4.b;}
| STR '<' STR {}
| STR '>' STR {}
| STR '=' '=' STR {}
| STR '<' '=' STR {}
| STR '>' '='STR {}
| TF {$$.b=$1.b;}
prin:PRINT STR {int i=check($2.ch);prints($2.ch,i);}
calculation:INT STR '=' NUMBER{m1[$2.ch]=v.size();m2[$2.ch]="int";v.push_back($4.n);}
| STRING STR '=' STR{m1[$2.ch]=s.size();m2[$2.ch]="string";s.push_back($4.ch);}
| BOOL STR '=' STR{m1[$2.ch]=b.size();m2[$2.ch]="bool";string test($2.ch),temp("true");b.push_back(test==temp?true:false);}
%%
void yyerror(const char *s) {
printf("%s\n", s);
}
int check(char* str)
{
int i=0;
string str1="int",str2="string",str3="bool";//可以任意设
string test(m2[str]);
if(test==str1)//
i=1;
else if(test==str2)
i=2;
else if(test==str3)
i=3;
else
i=4;
return i;
}
void prints(char* str,int i)
{
string test(str);
switch(i)
{
case 1: cout<<str<<"="<<v[m1[test]];break;
case 2: cout<<str<<"="<<s[m1[test]];break;
case 3: cout<<str<<"="<<(b[m1[test]]?"true":"false");break;
dafault: cout<<"错误类型";break;
}
cout<<endl;
}
int main(void) {
yyparse();
return 0;
}