编译原理与技术 实验1
环境配置 配置mingw64 bison flex,不再赘述 环境安装已完成如图:
lex_alone 注意到,执行flex lex.l后生成了lex.yy.c文件 执行cc .\lex.yy.c -o hello后生成了可执行文件hello.exe, 运行hello.exe,用户执行输入 其中”hi”、”oi”等词法是被允许的,因此输入之后也得到了对应的返回,规定之外的则为不合法,返回Unknown char
1 2 3 4 ("hi" |"oi" )"\n" { printf ("Got HI token\n" ); } ("tchau" |"bye" )"\n" { printf ("Got BYE token\n" ); } [-+.,><] { printf ("Other char: %c\n" , yytext[0 ]); } . { printf ("Unknown char: %c\n" , yytext[0 ]); }
hello_world 本样例将简单的词法分析和语法分析结合起来,通过
将语法限定为hi hi bye 我们输入对应的hi oi bye 得到对应的正确返回 (其中oi是符合hi词法的,语法分析要求的不是单独的词,而是符合对应词法的任何词组成的合法的语法)
自己设计的代码 设计了一个能够在有限词法库里识别主谓宾三种词法,并且按照“主谓宾”的顺序排序的语法分析
将 I , You , He , She , It 识别为主语 将 love , hate 识别为谓语 将 computer science , TJU 识别为宾语
在语法分析器中,所需要的语法格式为subject verb object,并且在正确输入对应语法后,print输入的完整句子
test.l:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 %{ #include "test.tab.h" #include <string.h> #include <stdlib.h> #include <stdio.h> int yyerror (const char *s) ; int yyparse () ; %} %% ("I" |"You" |"He" |"She" |"It" )"\n" { yylval.str = strdup(yytext); return Subject; } ("love" |"hate" )"\n" { yylval.str = strdup(yytext); return Verb; } ("computer science" |"TJU" )"\n" { yylval.str = strdup(yytext); return Object; } . { yyerror("Unknow char" ); } %% int main (void ) { yyparse(); return 0 ; } int yywrap (void ) { return 0 ; }
test.y:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 %{ #include <stdio.h> #include <stdlib.h> #include <string.h> int yylex (void ) ; int yyerror (const char *s) ; char *subject_str = NULL ; char *verb_str = NULL ; char *object_str = NULL ; void print_sentence () { if (subject_str && verb_str && object_str) { subject_str[strcspn (subject_str, "\n" )] = 0 ; verb_str[strcspn (verb_str, "\n" )] = 0 ; object_str[strcspn (object_str, "\n" )] = 0 ; printf ("Your sentence: %s %s %s\n" , subject_str, verb_str, object_str); } if (subject_str) free (subject_str); if (verb_str) free (verb_str); if (object_str) free (object_str); subject_str = NULL ; verb_str = NULL ; object_str = NULL ; } %} %token Subject Verb Object %union { char *str; } %token <str> Subject Verb Object %% program: subject verb object { print_sentence(); exit (0 ); } ; subject: Subject { subject_str = $1 ; printf ("subject: %s" , $1 ); } ; verb: Verb { verb_str = $1 ; printf ("verb: %s" , $1 ); } ; object: Object { object_str = $1 ; printf ("object: %s" , $1 ); } ; %% int yyerror (const char *s) { fprintf (stderr , "Error: %s\n" , s); return 0 ; }
输入 I love TJU ,则词法正确,语法正确,返回正确响应”Your sentence: I love TJU” 输入 I love love ,则词法正确,语法错误(在有限的词法库内,我们不考虑love做名词成为宾语的情况),则返回parse error 输入 I hate NKU ,则词法库中不包含NKU(即便我们知道NKU是宾语,句子也符合语法分析),则返回Unknown Char