• 《自制编程语言》笔记:使用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 "
    "   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 [ 	] ;
    24 .  {
    25     fprintf(stderr, "lexical error.
    ");
    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
    > ", $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
    ", 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 !
    ");
    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/

  • 相关阅读:
    Verilog设计Valid-Ready握手协议
    E203 CSR rtl实现分析
    E203 CSR寄存器
    RiscV汇编介绍(1)-编译过程
    RiscV汇编介绍(2)-编译过程
    博客迁移通知
    Visual Studio中的环境变量(以Visual Studio 2013为例)
    Android Studio搜索功能(查找功能)及快捷键图文详解
    《更好的解释(数学篇)》——后序
    《更好的解释(数学篇)》——第十二章
  • 原文地址:https://www.cnblogs.com/fengbohello/p/4634073.html
Copyright © 2020-2023  润新知