《自制编程语言》笔记:使用yacc与lex制作简单计算器

1、代码

  1.1)test.l

  1.2)test.y

  1.3)Makefile  (因为是在linux环境下,所以使用了Makefile)

2、编译与运行

  2.1)编译

  2.2)运行



1、代码(也可以在我的百度网盘下载:http://pan.baidu.com/s/1o65k7v8

  1.1)lex文件 test.l

 1 %{
 2 #include <stdio.h>
 3 #include "y.tab.h"
 4
 5 int
 6 yywrap(void)
 7 {
 8     return 1;
 9 }
10 %}
11 %%
12 "+"    return ADD;
13 "-"    return SUB;
14 "*"    return MUL;
15 "/"    return DIV;
16 "\n"   return CR;
17 ([1-9][0-9]*)|0|([0-9]+\.[0-9]*) {
18     double temp;
19     sscanf(yytext, "%lf", &temp);
20     yylval.double_value = temp;
21     return DOUBLE_LITERAL;
22 }
23 [ \t] ;
24 .  {
25     fprintf(stderr, "lexical error.\n");
26     exit(1);
27 }
28 %%

  1.2)yacc文件text.y

 1 %{
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #define  YYDEBUG 1
 5 %}
 6 %union {
 7     int     int_value;
 8     double  double_value;
 9 }
10 %token <double_value> DOUBLE_LITERAL
11 %token ADD SUB MUL DIV CR
12 %type <double_value> expression term primary_expression
13 %%
14 line_list
15     : line
16     | line_list line
17     ;
18 line
19     : expression CR
20     {
21         printf(">>%lf\n> ", $1);
22         fflush(stdout);
23     }
24 expression
25     : term
26     | expression ADD term
27     {
28         $$ = $1 + $3;
29     }
30     | expression SUB term
31     {
32         $$ = $1 - $3;
33     }
34     ;
35 term
36     : primary_expression
37     | term MUL primary_expression
38     {
39         $$ = $1 * $3;
40     }
41     | term DIV primary_expression
42     {
43         $$ = $1 / $3;
44     }
45     ;
46 primary_expression
47     : DOUBLE_LITERAL
48     ;
49 %%
50 int
51 yyerror(char * str)
52 {
53     extern char * yytext;
54     fprintf(stderr, "parser error near %s\n", yytext);
55     return 0;
56 }
57
58 int main(void)
59 {
60     extern int yyparse(void);
61     extern FILE * yyin;
62
63     printf("> ");
64     fflush(stdout);
65     yyin = stdin;
66     if (yyparse()) {
67         fprintf(stderr, "Error ! Error ! Error !\n");
68         exit(1);
69     }
70 }

  1.3)Makefile文件(其实不用Makefile的,我这里为了每次编译和清除的时候方面才使用的,以下的命令可以分三步手动执行,原著里面就是手动执行的)

1 .PHONY : dummy
2
3 all : dummy
4     yacc -dv test.y
5     lex test.l
6     gcc -o test lex.yy.c y.tab.c
7
8 clean : dummy
9     rm -rf lex.yy.c test y.output y.tab.c y.tab.h


2、编译与运行

  2.1)编译

1 $ make
2 yacc -dv test.y
3 lex test.l
4 gcc -o test lex.yy.c y.tab.c

  2.2)运行

1 $ ls
2 lex.yy.c  Makefile  readme.txt  test  test.l  test.y  y.output  y.tab.c  y.tab.h
3 $ ./test
4 > 1 + 2 * 3-4+2*3/7
5 >>3.857143
6 > q
7 lexical error.

来源:《自制编程语言》第二章

百度百科:http://baike.baidu.com/link?url=WC3BGKHo7gMEuPbxrX8Wsa6-KD69HLbRjd6TnmGPZNcq9j7xtgZxXh7RPufn2ISHIwW6A8Zri6Qt_5xViF9Vi_

豆瓣:http://book.douban.com/subject/25735333/

时间: 07-09

《自制编程语言》笔记:使用yacc与lex制作简单计算器的相关文章

利用yacc和lex制作一个小的计算器

买了本<自制编程语言>,这本书有点难,目前只是看前两章,估计后面的章节,最近一段时间是不会看了,真的是好难啊!! 由于本人是身处弱校,学校的课程没有编译原理这一门课,所以就想看这两章,了解一下编译原理,增加一下自己的软实力.免得被别人鄙视. 一.安装yacc和lex 我是在Windows下使用这两个软件的.所以使用bison代替yacc,用flex代替lex.两者的下载地址是http://sourceforge.net/projects/winflexbison/ 我的gcc环境是使用以前用过

1.C#WinForm基础制作简单计算器

利用c#语言编写简单计算器: 源码如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace 简单计算器 { public partial class Form1 : Form { public For

winform制作简单计算器

1 public Form1() 2 { 3 InitializeComponent(); 4 textBox2.Text = "0";//主显示屏 5 textBox1.Text = "";//顶端副显示屏 6 textBox3.Text = "";//中间变量,隐藏 7 8 } 9 10 private void Form1_Load(object sender, EventArgs e) 11 { 12 13 } 14 //数字按键 15

Yacc 与 Lex 快速入门

Yacc 与 Lex 快速入门 Lex 与 Yacc 介绍 Lex 和 Yacc 是 UNIX 两个非常重要的.功能强大的工具.事实上,如果你熟练掌握 Lex 和 Yacc 的话,它们的强大功能使创建 FORTRAN 和 C 的编译器如同儿戏.Ashish Bansal 为您详细的讨论了编写自己的语言和编译器所用到的这两种工具,包括常规表达式.声明.匹配模式.变量.Yacc 语法和解析器代码.最后,他解释了怎样把 Lex 和 Yacc 结合起来. 5 评论 Ashish Bansal ([ema

Yacc 与 Lex 快速入门(词法分析和语法分析)

我们知道,高级语言,一般的如c,Java等是不能直接运行的,它们需要经过编译成机器认识的语言.即编译器的工作. 编译器工作流程:词法分析.语法分析.语义分析.IR(中间代码,intermediate Representation)产生.IR优化.代码产生.最终优化: 我们这里主要介绍的是语法分析: Lex 代表 Lexical Analyzar.Yacc 代表 Yet Another Compiler Compiler. 让我们从 Lex 开始吧. Lex Lex 是一种生成扫描器的工具.扫描器

【FLEX&amp;YACC】第二天制作一个简单计算器

首先写词法分析器: 词法分析器要返回记号: "+" 返回ADD "-" 返回SUB "*" 返回MUL "/" 返回DIV 输入的实数全部被当作double类型处理 换行符返回CR calc.l: %{#include <stdio.h>#include "y.tab.h"int yywrap(void){ /*免链接库文件*/    return 1;}%}%%[ \t]    { ;}&qu

手把手带你自制Linux系统之二 简易Linux制作

手把手带你自制Linux系统之二 简易Linux制作 本文利用CentOS5.5自带内核制作一个Mini Linux. 打开准备工作中创建的CentOS,为另一个虚拟机MiniLinux添加一个最小Linux所需要的文件. 1. 创建分区 为准备好的磁盘创建两个主分区,大小分别为20M和512M. 使用fdisk命令创建分区详细过程: fdisk /dev/hda 创建第一个20M分区依次输入: n --> p --> 1 --> <Enter> --> +20M 这几

(怒)自制编程语言

对于这方面的资料,我实在是看不下去了,真是让人非亲自动手不可.上场yacc和lex,满口os和汇编,这让人怎么搞? 造轮子?对.虽然砌砖才是该干的事--下面开始. 要做些什么? 目的之一是可以自行添加特性,之二是对匹配方法很反感,另外我一直相信能用谁都看得懂的方法做出大事.至于我为什么这么想--是因为我在接触python前还接触过另一门语言--scheme--这可能导致了我奇怪的思维方式,比如"算术表达式怎么能一下子列完呢?"虽然我没有用scheme写过任何东西,更看不惯那么多括号.

JSP制作简单登陆

JSP制作简单登陆界面 运行环境 eclipse+tomcat+MySQL 不知道的可以参考Jsp运行环境--Tomcat 项目列表 这里我先把jsp文件先放在Web-INF外面访问 需要建立的几个文件在图上.jsp 还要导入MySQL的jar包mysql-5.0.5.jar,导到WEB-INF中的lib文件夹就可以不需要Bulid Path 开始编写代码: 代码演示: index.jsp就好像一般网站的首页一样感觉,将header.jsp和footer.jsp引入其中 <%@ page lan