科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件词法分析器制作与应用

词法分析器制作与应用

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

词法分析器制作与应用。

作者:山抹微云 来源:CSDN 2008年3月22日

关键字: 分析器 C C++ 词法 Linux

  • 评论
  • 分享微博
  • 分享邮件

词法分析器制作与应用
设计思想
(1)程序主体结构部分:
说明部分
%%
规则部分
%%
辅助程序部分
(2)主体结构的说明
在这里说明部分告诉我们使用的LETTER,DIGIT, IDENT(标识符,通常定义为字母开头的字母数字串)和STR(字符串常量,通常定义为双引号括起来的一串字符)是什么意思.这部分也可以包含一些初始化代码.例如用#include来使用标准的头文件和前向说明(forward ,references).这些代码应该再标记"%{"和"%}"之间;规则部分>可以包括任何你想用来分析的代码;我们这里包括了忽略所有注释中字符的功能,传送ID名称和字符串常量内容到主调函数和main函数的功能.
(3)实现原理
程序中先判断这个句语句中每个单元为关键字、常数、运算符、界符,对与不同的单词符号给出不同编码形式的编码,用以区分之。
PL/0语言的EBNF表示
<常量定义>::=<标识符>=<无符号整数>;
<标识符>::=<字母>={<字母>|<数字>};
<加法运算符>::=+|-
<乘法运算符>::=*|/
<关系运算符>::==|#|<|<=|>|>=
<字母>::=a|b|…|X|Y|Z
<数字>::=0|1|2|…|8|9
三:设计过程
1. 关键字:void,main,if,then,break,int,Char,float,include,for,while,printfscanf    并为小写。
2."+”;”-”;”*”;”/”;”:=“;”:”;”<“;”<=“;”>“;”>=“;”<>“;”=“;”(“;”)”;”;”;”#”为运算符。
3. 其他标记 如字符串,表示以字母开头的标识符。
4. 空格符跳过。
5. 各符号对应种别码
关键字分别对应1-13
运算符分别对应401-418,501-513。
字符串对应100
常量对应200
结束符#
四:举例说明
目标:实现对常量的判别
代码:
digit           [0-9]
letter          [A-Za-z]
other_char      [!-@\[-~]
id              ({letter}|[_])({letter}|{digit}|[_])*
string          {({letter}|{digit}|{other_char})+}
int_num         {digit}+

%%
[ |\t|\n]+
"auto"|"double"|"int"|"struct"|"break"|"else"|"long"|"switch"|"case"|"enum"|"register"|"typedef"|"char"|"extern"|"return"|"union"|"const"|"float"|"short"|"unsigned"|"continue"|"for"|"signed"|"void"|"default"|"goto"|"sizeof"|"do"|"if"|"static"|"while"|"main"         {Upper(yytext,yyleng);printf("%s,NULL\n",yytext);}
\"([!-~])*\"    {printf("CONST_string,%s\n",yytext);}
-?{int_num}[.]{int_num}?([E][+|-]?{int_num})?      {printf("CONST_real,%s\n",yytext);}
"0x"?{int_num} {printf("CONST_int,%s\n",yytext);}
","|";"|"("|")"|"{"|"}"|"["|"]"|"->"|"."|"!"|"~"|"++"|"--"|"*"|"&"|"sizeof"|"/"|"%"|"+"|"-"|">"|"<"|">="|"<="|"=="|"!="|"&"|"^"|"|"|"&"|"||"|"+="|"-="|"*="|"/="|"%="|">>="|"<<="|"&="|"^="|"|="|"="        {printf("%s,NULL\n",yytext);}
{id}    {printf("ID,%s\n",yytext);}

{digit}({letter})+   {printf("error1:%s\n",yytext);}

%%
#include <ctype.h>
Upper(char *s,int l)
{
        int i;
        for(i=0;i<l;i++)
        {
                s[i]=toupper(s[i]);
        }
}
yywrap()
{
        return 1;
}
五:DFA

六:数据测试
     
七:心得体会
其实匹配并不困难,主要是C++知识要求相对较高,只要把握住指针就好了。
附源程序:
#include<iostream.h>
#include<stdio.h>
#include<stdlib.h> 
#include<string.h>
int i,j,k,flag,number,status;
/*status which is use to judge the string is keywords or not!*/
char ch;
char words[10] = {" "};
char program[500];
int Scan(char program[])
{
    char *keywords[13] = {"void","main","if","then","break","int",
  "char","float","include","for","while","printf",
  "scanf"};
number = 0;
status   = 0;
j      = 0;
ch     = program[i++];
       /* To handle the lettle space ands tab*/

      /*handle letters*/
if ((ch >= 'a') && (ch <= 'z' ))
{
while ((ch >= 'a') && (ch <= 'z' ))
{
words[j++]=ch;
ch=program[i++];
}
  i--;
  words[j++] = '\0';
       for (k = 0; k < 13; k++)
 if (strcmp (words,keywords[k]) == 0)
switch(k)
{
case 0:{
 flag = 1;
 status = 1;
 break;
}
case 1:{
 flag = 2;
 status = 1;
 break;
}
case 2:{
 flag = 3;
 status = 1;
 break;
}
case 3:{
 flag = 4;
 status = 1;
 break;
}
case 4:{
 flag = 5;
 status = 1;
 break;
}
case 5:{
 flag = 6;
 status = 1;
 break;
       }
case 6:{
 flag = 7;
 status = 1;
 break;
       }
case 7:{
 flag = 8;
 status = 1;
 break;
       }
case 8:{
 flag = 9;
 status = 1;
 break;
       }
case 9:{
 flag = 10;
 status = 1;
 break;
       }
case 10:{
 flag = 11;
 status = 1;
 break;
}
case 11:{
 flag = 12;
 status = 1;
 break;
}
case 12:{
 flag = 13;
 status = 1;
 break;
}
}
   if (status == 0)
   {
      flag = 100;
   }
}
/*handle digits*/
else if ((ch >= '0') && (ch <= '9'))
{
number = 0;
while ((ch >= '0' ) && (ch <= '9' ))
{
number = number*10+(ch-'0');
ch     = program[i++];
}
flag = 200;
i--;
}
/*opereation and edge handle*/
else switch (ch)
{
case '=':{
   if (ch == '=')
     words[j++] = ch;
     words[j]   = '\0';
     ch         = program[i++];
     if (ch == '=')
     {
    words[j++] = ch;
    words[j]   = '\0';
    flag       = 401;
     }
     else
     {
    i--;
    flag       = 402;
     }
   break;
 }
case'>':{
 if (ch == '>')
       words[j++] = ch;
       words[j]   = '\0';
       ch         = program[i++];
   if (ch == '=')
   {
       words[j++] = ch;
       words[j]   = '\0';
       flag       = 403;
   }
   else
   {
       i--;
       flag       = 404;
   }
  break;
}
case'<':{
     if (ch == '<')
        words[j++] = ch;
        words[j]   = '\0';
        ch         = program[i++];
        if (ch == '=')
{
    words[j++] = ch;
    words[j]   = '\0';
    flag       = 405;
}
        else
{
    i--;
    flag       = 406;
}
    break;
}
case'!':{
    if (ch == '!')
       words[j++] = ch;
       words[j]   = '\0';
       ch         = program[i++];
     if (ch == '=')
     {
       words[j++] = ch;
       words[j]   = '\0';
       flag       = 407;
     }
     else
     {
    i--;
       flag       = 408;
     }
    break;
}
case'+':{
   if (ch == '+')
      words[j++] = ch;
      words[j]   = '\0';
      ch         = program[i++];
     if (ch == '=')
     {
    words[j++] = ch;
    words[j]   = '\0';
    flag       = 409;
     }
     else if (ch == '+')
     {
    words[j++] = ch;
    words[j]   = '\0';
    flag       = 410;
     }
     else
     {
i--;
flag       = 411;
     }
   break;
}
case'-':{
  if (ch == '-')
   words[j++] = ch;
   words[j]   = '\0';
   ch         = program[i++];
   if (ch == '=')
   {
words[j++] = ch;
words[j]   = '\0';
flag       = 412;
   }
   else if( ch == '-')
   {
words[j++] = ch;
words[j]   = '\0';
flag       = 413;
   }
   else
   {
    i--;
flag       = 414;
   }
   break;
}
case'*':{
  if (ch == '*')
      words[j++] = ch;
      words[j]   = '\0';
      ch         = program[i++];
      if (ch == '=')
      {
   words[j++] = ch;
   words[j]   = '\0';
   flag       = 415;
      }
     else
     {
   i--;
   flag       = 416;
     }
   break;
 }
case'/':{
 if (ch == '/')
       words[j++] = ch;
       words[j]   = '\0';
       ch         = program[i++];
       if (ch == '=')
       {
       words[j++] = ch;
       words[j]   = '\0';
       flag       = 417;
       }
       else
       {
       i--;
       flag       = 418;
       }
  break;
}
case';':{
  words[j]   = ch;
  words[j+1] = '\0';
  flag       = 501;
  break;
 }
case'(':{
  words[j]   = ch;
  words[j+1] = '\0';
  flag       = 502;
  break;
 }
case')':{
  words[j]   = ch;
  words[j+1] = '\0';
  flag       = 503;
  break;
}
case'[':{
  words[j]   = ch;
  words[j+1] = '\0';
  flag       = 504;
  break;
 }
case']':{
  words[j]   = ch;
  words[j+1] = '\0';
  flag       = 505;
  break;
 }
case'{':{
  words[j]   = ch;
  words[j+1] = '\0';
  flag       = 506;
  break;
 }
case'}':{
  words[j]   = ch;
  words[j+1] = '\0';
  flag       = 507;
  break;
 }
case':':{
  words[j]   = ch;
  words[j+1] = '\0';
  flag       = 508;
  break;
}
case'"':{
  words[j] = ch;
  words[j+1] = '\0';
  flag = 509;
  break;
}
case'%':{
   if (ch == '%')
       words[j++] = ch;
       words[j]   = '\0';
       ch         = program[i++];
       if (ch == '=')
       {
       words[j++] = ch;
       words[j]   = '\0';
       flag       = 510;
       }
       else
       {
       i--;
       flag       = 511;
       }
     break;
}
case',':{
 words[j] = ch;
 words[j+1] = '\0';
 flag = 512;
 break;
}
case'#':{
 words[j] = ch;
 words[j+1] = '\0';
 flag = 513;
 break;
}
case'@':{
 words[j] = '#';
 flag = 0;
 break;
}
default:{
 flag = -1;
 break;
}
}
return flag;
}
main()
{
i=0;
printf("please input a program end with @");
do
{
  ch           = getchar();
  program[i++] = ch;
}while(ch != '@');
 i = 0;
do{
  flag = Scan(program);
  if (flag == 200)
  {
printf("(%2d,%4d)",flag,number);
  }
  else if (flag == -1)
  {
printf("(%d,error)",flag);
  }
  else
  {
printf("(%2d,%4s)",flag,words);
  }
}while (flag != 0);
    system("pause");
}
 

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章