📄 ysh_0.3.y
字号:
%{#include <stdio.h>#include <ctype.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>#define LEN 20%}%union { char *sym; //词法分析栈中的存放的数据类型.即分析出的词法记号都是字符串的形式}%token String //String是要分析出的词法记号%right '&' //'&'是右结合的优先级%type <sym> String ExecFile //String和ExecFile都是字符串指针类型%type <sym> '&'%%//下面定义了命令的语法规则,一共4条规则,采用正则表达式形式,规则后面花括号中是要执行的语法动作.也就是C函数Command: //NULL | Command '\n' { printf("ysh>"); } | Command Prog '\n' { make_exec(); reset(); printf("ysh>"); } | Command Prog '&' '\n' { make_bgexec(); reset(); printf("ysh>"); } ;Prog: ExecFile Args { } ;ExecFile: String { push(); } //将分析出的命令压栈 ;Args: | Args String { push(); } //将分析出的命令参数压栈 ;%%char *backjobs="&";char *stack[LEN];char buf[100]; //存放分析出来的字符串char *p=buf;char *path[]={"/bin/","/usr/bin/",NULL}; //外部程序命令的路径int lineno=0;int top=0;int main(int argc,char* argv[]) //主程序入口{ printf("ysh>"); yyparse(); //语法分析函数,由yacc自动生成,其分析过程按照前面定义的规则进行} yylex() //词法分析函数,函数名是默认的,其内容由程序员编写,完成词法分析的任务{ int c; p=buf; while ((c=getchar())==' ' || c=='\t'); if (c==EOF) //EOF Crtl+D return 0; //exit to program if (c!='\n') { do { *p++=c; c=getchar(); } while (c!=' ' && c!='\t' && c!='\n'); ungetc(c,stdin); *p='\0'; yylval.sym=buf; if (!strcmp(buf,backjobs)) return '&'; else return String; } else { lineno++; } return c;}yyerror(char *s) //出错处理函数,当语法分析产生错误时就会自动调用此函数{ warning(s,(char*)0);}warning(char *s, char *t){ if (t) fprintf(stderr,"%s",t); fprintf(stderr," errno near line %d\n",lineno);}make_bgexec() //语法分析过程中要执行的动作函数,这里执行分析出来的命令,下面的函数作用与此相同{ pid_t pid; char temp[50]; char *p_path; int i=0,ret=0; if ((pid=fork())<0) { perror("fork failed"); exit(EXIT_FAILURE); } if (!pid) { //child process while ((p_path=path[i])!=NULL) { strcpy(temp,stack[0]); strcpy(stack[0],path[i]); strcat(stack[0],temp); i++; ret=execv(stack[0],stack); if (ret<0) strcpy(stack[0],temp); } if (ret<0) printf("ysh:command not found\n"); } if (pid>0) { //father process waitpid(pid,NULL,WNOHANG); }}make_exec(){ pid_t pid; char temp[50]; char *p_path; int i=0,ret=0; if ((pid=fork())<0) { perror("fork failed"); exit(EXIT_FAILURE); } if (!pid) { //child process while ((p_path=path[i])!=NULL) { strcpy(temp,stack[0]); strcpy(stack[0],path[i]); strcat(stack[0],temp); i++; ret=execv(stack[0],stack); if (ret<0) strcpy(stack[0],temp); } if (ret<0) printf("ysh:command not found\n"); } if (pid>0) { //father process waitpid(pid,NULL,0); }}reset(){ int i; for (i=0; i<top; i++) { free(stack[i]); stack[i]=NULL; } top=0;}push(){ char *temp=NULL; if (top==0) temp=(char*)malloc(sizeof(char)*100); else temp=(char*)malloc(strlen(buf)+1); strcpy(temp,buf); stack[top]=temp; top++;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -