《自制编程语言》的学习

前言

前不久,入手了一本《自制编程语言》。这里记录一下我的学习过程和遇到的困难。

1.配置环境

我这里直接用的下载了虚拟机,里面安装的Ubuntu系统。

里面安装的flexbison

2.一个小项目

第一章就是做一个计算器,这里作者并没有直接用c语言来进行制作。而是先使用了lexbison这两个工具进行制作。

lex是自动生成词法分析的工具,可以根据你写的代码,输出词法分析的c语言代码。

至于词法分析器,就是将输入的字符串分割为记号的程序。然后给语法分析器来分析执行相应代码。

%{
#include <stdio.h>
#include "y.tab.h"

int
yywrap(void)
{
  return 1;
}
%}
%%
"+"             return ADD;//定义加号
"-"             return SUB//定义减法
"*"             return MUL//定义乘法
"/"             return DIV//定义除法
"\n"           return CR;//定义换行
([1-9][0-9]*)|0|([0-9]+\.[0-9]*) {
  double temp;
  sscanf(yytext, "%lf", &temp);
  yylval.double_value = temp;
  return DOUBLE_LITERAL;
}//这个地方用正则进行匹配,返回标记DOUBLE_LITERAL
[ \t] ;
. {
  fprintf(stderr, "lexical error.\n");
  exit(1);
}
%%

这里首先执行了#include <stdio.h>导入了c语言的头文件,在下面定义了记号。这里是词法分析器,对你输入的代码进行分析。

比如你输入1+1.应该就是被分割成DOUBLE_LITERAL  ADD  DOUBLE_LITERAL。

语法分析器

%{
#include <stdio.h>
#include <stdlib.h>
#define YYDEBUG 1
%}
%union {
  int         int_value;
  double       double_value;
}
%token <double_value>     DOUBLE_LITERAL
%token ADD SUB MUL DIV CR
%type <double_value> expression term primary_expression
%%
line_list
  : line
  | line_list line
  ;
line
  : expression CR
  {
      printf(">>%lf\n", $1);
  }
expression
  : term
  | expression ADD term
  {
      $$ = $1 + $3;
  }
  | expression SUB term
  {
      $$ = $1 - $3;
  }
  ;
term
  : primary_expression
  | term MUL primary_expression
  {
      $$ = $1 * $3;
  }
  | term DIV primary_expression
  {
      $$ = $1 / $3;
  }
  ;
primary_expression
  : DOUBLE_LITERAL
  ;                
%%
int
yyerror(char const *str)
{
  extern char *yytext;
  fprintf(stderr, "parser error near %s\n", yytext);
  return 0;
}

int main(void)
{
  extern int yyparse(void);
  extern FILE *yyin;

  yyin = stdin;
  if (yyparse()) {
      fprintf(stderr, "Error ! Error ! Error !\n");
      exit(1);
  }
}

这里对语法进行分析,对开始的词法分析器传过来的进行匹配,并执行相应的操作。比如lex的词法分析器传过来一个1+1.被分解成DOUBLE_LITERAL  ADD  DOUBLE_LITERAL。在这里1先匹配到primary_expression。在又由primary_expression匹配到term.再匹配到

expression。+则没有匹配到任何东西,就是ADD。此时变成了expression ADD 。1再传进来就匹配到了expression ADD term。从而执行 $$ = $1 + $3;这里的$1对应的是1,$2对应是+,$3对应的也是1.$$就是最终的值。

编译项目

yacc -dv mycalc.y
lex mycalc.l
cc -o mycalc y.tab.c lex.yy.c

这三个命令进行编译

运行

最激动人心的地方到了,运行!!!

运行成功!!!

学习交流群342096685

猜你喜欢

转载自blog.csdn.net/qq_59848320/article/details/123649160