编译原理与技术lab1

编译原理与技术 实验1

环境配置

配置mingw64 bison flex,不再赘述
环境安装已完成如图:
img1

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]); }

img2

hello_world

本样例将简单的词法分析和语法分析结合起来,通过

1
2
3
program:
hi hi bye
;

将语法限定为hi hi bye
我们输入对应的hi oi bye 得到对应的正确返回
(其中oi是符合hi词法的,语法分析要求的不是单独的词,而是符合对应词法的任何词组成的合法的语法)

img3

自己设计的代码

设计了一个能够在有限词法库里识别主谓宾三种词法,并且按照“主谓宾”的顺序排序的语法分析

将 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

img4