小白说编译原理-2-lex基本用法

来源:互联网 发布:plc编程入门梯形图 编辑:程序博客网 时间:2024/05/16 08:21

lex词法分析器

概述

1,使用lex语言书写一套正规表达式的规则,命名为lex.l
2,由lex编译器负责将lex.l编译为lex.h和lex.cpp,这两个文件包含了lex定义的规则
3,再使用标准的c++编译器即可以将lex.cpp编译生成可执行程序lex.exe
4,lex.exe识别输入流,并将其转换为字符序列,并执行相应的操作(在lex.l中定义)

lex样例

%{/***/%}// lexical analyser name%name lexer%%[ \t]+ {printf(" ");}\n|.    {printf("%s", yytext);}%%int main(){//create a lexer, and call the lex function.//it will read from stdin and parser the tokens. YYLEXERNAME lexer; if(lexer.yycreate()){     lexer.yylex(); }}

简单的语法结构

声明段:

         %{                c++语言代码,一般为头文件包含,以及变量声明,定义。                注意:代码会被原样copy到生成的代码文件中。         %}         正规定义

规则段:

%%    用户定义的转换规则    P1 {action}    P1表示正规表达式,action为相应的执行动作。%%

子程序段:

    主要包含用户子程序代码,代码会被原样copy到生成的代码文件中。

解析说明例子

  1. %name lexer
    这是说明词法分析器的类名字为lexer,最后生成的代码中会有 #define YYLEXERNAME lexer。
  2. [ \t]+ {printf(” “);}
    前面是表达式,后面{}中是进行的动作。 [ \t]+表示连续的空白字符(空格,tab), 进行的语义动作是打印一个空格。
  3. \n|. {printf(“%s”, yytext);}
    其他任意字符,原样打印。因为.无法表达\n这样的字符,所以使用|的或操作。
  4. 功能说明
    将连续的空格或者tab压缩为一个空格,其他字符原样输出。

lex样例2,解析token

%{#include <iostream>using namespace std;enum{LT,  EQ, GT, IF, ELSE, ID, NUMBER, PLUS, MINUS, TIMES, OVER, INT, DOUBLE,CHAR};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 lexerdelim [ \t\n]ws    {delim}+letter [a-zA-Z]digit [0-9]id    {letter}({letter}|{digit})*/* can support 12.34 */number {digit}+(\.{digit}+)?%%{ws} {/* do nothing */}"int"  {print_token(INT, yytext);}"double"  {print_token(DOUBLE, yytext);}"char"  {print_token(CHAR, yytext);}"+"         {print_token(PLUS, yytext); }"-"         {print_token(MINUS, yytext);}"*"         {print_token(TIMES, yytext);}"/"         {print_token(OVER, yytext); }{id}        {print_token(ID, yytext);}{number}    {print_token(NUMBER, yytext);}%%static void print_token(int token, char* lex){    cout<<"token:" << tokenStr[token]<<" "<<"lex:"<<lex<<endl;}int main(){//create a lexer, and call the lex function.//it will read from stdin and parser the tokens. YYLEXERNAME lexer; if(lexer.yycreate()){     lexer.yylex(); }}

样例2说明

  1. 最前面的%{ … %}内的为变量以及函数声明部分
  2. %name lexer 定义词法分析器的名字
  3. delim [ \t\n] 这些是正规的定义,通过递归的定义可以定义更复杂的正规式,例如id和number的定义
  4. %% … %% 正规表达式与执行的动作的绑定
  5. 最后的函数实现代码为整个驱动程序,它读取用户输入,并解析token,执行action

下节内容

yacc语法程序,能够实现一个简单的四则运算。

本人lpstudy,转载请注明出处: http://blog.csdn.net/lpstudy/article/details/51224869

0 0