Install and configure Ubuntu WSL
Search the control panel, enter 控制面板
, select 程序
, click 启用或关闭Windows功能
, check 适用于Linux的Windows子系统
, as follows:
Restart the system as prompted.
After restarting, search in the Microsoft Store Ubuntu
, download and install version 18.04, as follows:
Start after installation, and set the computer name and password as prompted. Use the following command to back up the original source file and change the software source:
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
sudo vim /etc/apt/sources.list
/etc/apt/sources.list
After commenting out all sources in the file , add the following Tsinghua source information:
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse
Use the command to update after saving and exiting, as follows:
sudo apt-get update
Configure VS Code
Because there is a file and code editing part, download the VS Code plug- Remote WSL
in for WSL to open and edit the file in WSL. Specifically: search in the extension part of VS Code Remote WSL
, and then install it, as shown below:
The usage method is: enter in WSL code .
to start VS Code.
Install flex and bison
Use the following commands to install flex and bison as follows:
sudo apt-get install flex bison
After the installation is complete, use to apt list [name]
check the installation situation and find that the installation is successful, as follows:
lexical analysis
%{
#include "fb_calc_lyg.tab.h"
%}
%%
"+" {
return ADD; }
"-" {
return SUB; }
"*" {
return MUL; }
"/" {
return DIV; }
"|" {
return ABS; }
[0-9]+ {
yylval = atoi(yytext); return NUMBER; }
\n {
return EOL; }
[ \t] {
}
. {
}
%%
The ADD, SUB and other return values used are already defined by flex, so you can call them directly.
Semantic Analysis
%{
#include <stdio.h>
void yyerror();
void main();
int yylex();
%}
%token NUMBER
%token ADD SUB MUL DIV ABS
%token EOL
%%
calclist:
| calclist exp EOL {
printf("= %d\n", $2); }
;
exp: factor {
$$ = $1; }
| exp ADD factor {
$$ = $1 + $3; }
| exp SUB factor {
$$ = $1 - $3; }
;
factor: term {
$$ = $1; }
| factor MUL term {
$$ = $1 * $3; }
| factor DIV term {
$$ = $1 / $3; }
;
term: NUMBER {
$$ = $1; }
| ABS term {
$$ = $2 >= 0 ? $2 : -$2; }
;
%%
void yyerror(char *s)
{
fprintf(stderr, "error: %s\n", s);
}
void main(){
yyparse();
}
The second part of the entire structure completes the description of the language grammar, which $$
represents the result, $1、$2...
and so on, in turn, represents the non-terminal symbols on the right side of the grammar. Specific examples are shown:
exp: factor {
$$ = $1; }
| exp ADD factor {
$$ = $1 + $3; }
| exp SUB factor {
$$ = $1 - $3; }
;
All of $$
them refer to the non-terminal symbol exp, and the result will also be assigned to exp; the first row $1
represents the value of factor; the second row corresponds to exp $1
, ADD corresponds $2
to factor $3
, and the third row corresponds to exp $1
, SUB corresponds to $2
, and factor corresponds to $3
.
The yyerror() function overwrites the function of the same name defined by flex to complete a custom error response. Use the yyparse() function to complete the semantic analysis.
Compile
Since there are many compilation commands, it is handed over to make
management. First, create a new folder and file
put the written lexical analysis file fb_calc_lyg.l
and syntax analysis file fb_calc_lyg.y
into this folder, and then create a Makefile
file to record the command and related file information, as follows:
fb_calc_lyg: fb_calc_lyg.l fb_calc_lyg.y
bison -d fb_calc_lyg.y
flex fb_calc_lyg.l
cc -o $@ fb_calc_lyg.tab.c lex.yy.c -lfl
Makefile
The format is:
TARGET : DEPENDENCIES …
COMMAND …
TARGET: represents the target file to be generated
DEPENDENCIES: Specify the input file used to generate the target. A target usually depends on multiple files
COMMAND: Command line
After creation Makefile
, execute the make
command directly under the folder where it is located , and the compilation result is as follows:
Ignore the warning message and successfully complete the compilation.
test
Run and test with the following command:
./fb_calc_lyg
It was observed that the simple four arithmetic operations were successfully completed.
Elimination of errors and warnings
NO.1
bison -d fb_calc_lyg.y
fb_calc_lyg.y:16.21-22: error: invalid characters: ‘$$’
exp: factor default $$ = $1;
^^
fb_calc_lyg.y:16.24: error: syntax error, unexpected =
exp: factor default $$ = $1;
^
fb_calc_lyg.y:16.26: error: invalid character: ‘$’
exp: factor default $$ = $1;
^
fb_calc_lyg.y:17.5: error: syntax error, unexpected |
| exp ADD factor { $$ = $1 + $3; }
^
Makefile:2: recipe for target ‘fb_calc_lyg’ failed
make: *** [fb_calc_lyg] Error 1
The main reason is that this version of bsion does not support the default keyword, just delete it. At the same time, since the $$ = $1;
statement is a C language assignment statement, curly braces are also required.
NO.2
fb_calc_lyg.y:29:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
main(){
^~~~
fb_calc_lyg.y:33:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
yyerror(char *s)
The function lacks the warning message of the return value, just add void
the return value declaration of the type to both functions .
NO.3
/tmp/ccVulWce.o: In function ‘main’:
lex.yy.c:(.text+0x1d62): multiple definition of ‘main’
/tmp/ccsoplHV.o:fb_calc_lyg.tab.c:(.text+0xa06): first defined here
collect2: error: ld returned 1 exit status
Makefile:2: recipe for target ‘fb_calc_lyg’ failed
make: *** [fb_calc_lyg] Error 1
Since .l
the main function in the file was not deleted at the beginning of writing, two main functions appeared; just delete .l
the main function in the file.
NO.4
fb_calc_lyg.tab.c: In function ‘yyparse’:
fb_calc_lyg.tab.c:1126:16: warning: implicit declaration of function ‘yylex’ [-Wimplicit-function-declaration]
yychar = yylex ();fb_calc_lyg.tab.c:1306:7: warning: implicit declaration of function ‘yyerror’; did you mean ‘yyerrok’? [-Wimplicit-function-declaration]
yyerror (YY_(“syntax error”));
^~~~~~~
yyerrok
Since the yylex() function is a function generated when flex converts a .l
file to a lex.yy.c
file, the .tab.c
file does not contain the declaration of this function during the linking process , so a warning message will appear. Just .y
declare it in the file int yylex();
.
Because yyerror() is directly defined without prior declaration, a warning message is generated. The gcc compiles the C program and the writing method does not report an error. The reason is that bison will convert the .y
file into a .tab.c
file and a .tab.h
file, and the subsequent connection process will use the .tab.c
file to connect, so during the conversion process, .y
the C code of the file read by bison There is no related function declaration in part, so the converted .tab.c
file also has no related function declaration, which leads to the generation of warning messages.