zoukankan      html  css  js  c++  java
  • 小白说编译原理lex和yacc环境配置-多图

    lex和yacc的使用很简单,但环境配置却是各种问题,本章说明lex和yacc在windows下的环境配置。

    软件需求:
    系统 win7-64位(win7-32, win8, win10全部通过)
    c++编译器: vs2010(2008,2013,2015也全部通过)
    lex和yacc编译器: ParGen.exe

    基本流程:
    安装Pargen.exe,采用的默认目录安装在C:Program Files (x86)Parser Generator 2
    安装vs2010,这个各种教程,不再赘述

    启动Pargen程序,并选择Project->ParserWizard…
    这里写图片描述

    选中ParserWizard,开始工程的创建,此处我创建功能,命名为Test,目录位置可自己选择,目标语言为C++,编译器为vc++(32-bit)
    这里写图片描述

    下一步,选择是创建lex,还是yacc,还是两者兼有。此处我选择是lex和yacc都有,准备实现一个不支持变量的计算器,使用lex识别token,使用yacc识别语法。
    这里写图片描述

    下一步,设置yacc的文件名字以及使用的解析器,此处我使用的默认选项,不进行修改,文件名默认为myparser.y
    这里写图片描述

    下一步,设置lex的文件名以及使用的分析器的名字,此处我使用的默认选项,文件名默认为mylexer.l
    这里写图片描述

    点击完成按钮,创建工程完毕,同时有两个文件mylexer.l 和myparser.y
    这里写图片描述

    工程的管理,可使用window->project菜单,查看工程下的所有文件
    这里写图片描述
    这里写图片描述

    当你点击文件编辑窗口的放大按钮,会将其他的文件编辑覆盖,此时可以使用window->project菜单查看,也可以使用window->Tile vertically查看全部文件的平铺
    这里写图片描述

    编辑mylexer.l文件,粘贴入以下内容:

    %{
    //this code will be added into the header of generated .cpp file
    #include <iostream>
    #include "myparser.h"
    using namespace std;
    
    //already defined in yacc.y, use %token...
    //enum{LT,  EQ, GT, IF, ELSE, ID, NUMBER, PLUS, MINUS, TIMES, OVER, INT, DOUBLE,CHAR, LP,RP};
    
    const char* tokenStr[] = {"LT",  "EQ", "GT", "IF", "ELSE", "ID", "NUMBER", "PLUS", "MINUS", "TIMES", "OVER", "INT", "DOUBLE","CHAR"};
    static void print_token(int token, char* lex);
    
    %}
    
    %name mylexer
    
    delim [ 	]
    ws    {delim}+
    letter [a-zA-Z]
    digit [0-9]
    id    {letter}({letter}|{digit})*
    /* can support 12.34 */
    number {digit}+(.{digit}+)?
    
    
    %%
    %{
    //this code will be added into yyaction function
        YYSTYPE YYFAR& yylval = *(YYSTYPE YYFAR*)yyparserptr->yylvalptr;
        //double yylval;
    %}
    
    {ws} {/* do nothing */}
    "int"  {print_token(INT, yytext); return INT;}
    "double"  {print_token(DOUBLE, yytext);}
    "char"  {print_token(CHAR, yytext);}
    
    "+"         {print_token(PLUS, yytext); return PLUS;}
    "-"         {print_token(MINUS, yytext); return MINUS;}
    "*"         {print_token(TIMES, yytext); return TIMES;}
    "/"         {print_token(OVER, yytext); return OVER;}
    "("         {return LP;}
    ")"         {return RP;}
    "
    "        {return EOL;}
    {id}        { return ID;}
    {number}    { yylval = atof(yytext);return NUMBER;}
    "//".*      {return COMMENT;}
    "."          {printf("Mystery character %s
    ", yytext); }
    %%
    
    
    
    static void print_token(int token, char* lex)
    {
    #ifdef LEX_DEUB
        cout<<"token:" << token<<" "<<"lex:"<<lex<<endl;
    #endif
    }
    
    • 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
    • 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

    编译myparser.y文件,粘贴入以下内容

    %{
    #include "mylexer.h"
    %}
    
    
    
    %name myparser
    // class definition
    {
        // place any extra class members here
    }
    // constructor
    {
        // place any extra initialisation code here
    }
    
    // destructor
    {
        // place any extra cleanup code here
    }
    
    // place any declarations here
    %include {
    #ifndef YYSTYPE
    #define YYSTYPE double
    #endif
    }
    
    %token NUMBER ID
    %token PLUS MINUS TIMES OVER
    %token LP RP EOL COMMENT
    %TOKEN INT DOUBLE CHAR
    
    %left PLUS MINUS
    %left TIMES OVER
    %right UMINUS
    
    %%
    
    lines   :   lines expr EOL  { printf("%g
    ", $2); }
            |   lines EOL
            |  lines COMMENT
            |
            ;
    
    expr    :   expr PLUS expr  { $$ = $1 + $3; }
    		|	expr MINUS expr	{ $$ = $1 - $3; }
    		|	expr TIMES expr	{ $$ = $1 * $3; }
    		|	expr OVER expr	{ $$ = $1 / $3; }
    		|	LP expr RP	{ $$ = $2; }
    		|	'-' expr %prec UMINUS	{ $$ = -$2; }
    		|	NUMBER {$$=$1;} //$$=$1 can be ignored
            |   ID //should be complemented
            ;  
    %%
    
    
    
    int main(int argc, char *argv[])
    {
        printf("a cacluator which support +,-,*,/ and (): 
    ");
        printf("    e.g.  12.2+3*(2+5)
    ");
        int n = 1;
        mylexer lexer;
        myparser parser;
        if (parser.yycreate(&lexer)) {
            if (lexer.yycreate(&parser)) {
                //lexer.yyin = new ifstream(argv[1]);
                //lexer.yyout = new ofstream(argv[2]);
                n = parser.yyparse();
                //parse_tree.get_label();
                //parse_tree.gen_code(*lexer.yyout);
            }
        }
    
        getchar();
        return n;
    }
    
    • 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
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 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
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79

    点击Pargen右上角的编译build按钮,会生成相应的.h和.cpp代码
    这里写图片描述
    这里写图片描述

    新建vs2010工程,并将生成的.h和.cpp代码加入到工程中。简单起见,在compleTest目录下创建vs工程vsTest
    这里写图片描述

    选择控制台工程, 工程的目录,以及工程名称vsTest,点击确定按钮后
    这里写图片描述

    继续下一步配置
    这里写图片描述

    此处附件选项选择空项目,然后点击完成按钮,即完成vsTest工程创建
    这里写图片描述

    工程右键添加现有项,即添加已经生成.h和.cpp文件
    这里写图片描述
    这里写图片描述
    这里写图片描述

    在vs界面,点击编译按钮,查看当前的编译情况,会显示编译错误,找不到yy的头文件,这是因为并没有将Pargen安装后的头文件加入到工程的包含目录中
    这里写图片描述

    下面将Pargen安装后的头文件加入到工程include配置
    这里写图片描述
    这里写图片描述
    这里写图片描述

    在vs界面,点击编译按钮,查看编译情况。 当前头文件可以正常找到,会出现大量的链接错误-link error。这是因为对应的lib文件还没有加载进来。
    这里写图片描述

    下面加入库文件,加入库所在目录
    这里写图片描述

    加入要使用的库的名字:ylmtri.lib, 注意使用分号隔开
    这里写图片描述

    再次点击编译按钮,会发现可以编译,但是运行的时候,会出现ylmtri.dll的错误。这是因为我们使用动态dll库,需要将对应的dll文件从Pargen目录复制到工程目录的exe文件同级目录下
    这里写图片描述

    下面开始将ylmtri.dll从Pargen目录复制到vsTest.exe同级目录
    这里写图片描述
    这里写图片描述

    再次点击编译运行按钮,可以正常运行,效果如下
    这里写图片描述
    这里写图片描述

    终于完结了。

  • 相关阅读:
    js保存图片至本地
    ArrayLike
    key的作用
    react Video event
    react中字符串换行
    react打包后找不到静态文件
    2020软件工程第三次作业
    003 Longest Substring Without Repeating Characters
    002addTwoNumbers
    001twoSum
  • 原文地址:https://www.cnblogs.com/1996313xjf/p/6075582.html
Copyright © 2011-2022 走看看