编译原理之词法分析器-----pass!

Ivan 发表于 2005-5-18 20:49:00

请点击这里下载“词法分析器”源程序
#i nclude<cstdio>
#i nclude<iostream>
#i nclude<cstdlib>
#i nclude<fstream>
#i nclude<string>
#i nclude<cmath>
using namespace std;
struct token//token结构体
{
int code;
int num;
token *next;
};
token *token_head,*token_tail;//token队列
struct number//number结构体
{
int num;
int value;
number *next;
};
number *number_head,*number_tail;//number队列
struct str//string结构体
{
int num;
string  word;
str *next;
};
str *string_head,*string_tail;//string队列
void scan();//按字符读取源文件
int judge(char ch);//判断输入字符的类型
void out1(char ch);//写入token.txt
void out2(char ch,string word);//写入number.txt
void out3(char ch,string word);//写入string.txt
void input1(token *temp);//插入结点到队列token
void input2(number *temp);//插入结点到队列number
void input3(str *temp);//插入结点到队列string
void output();//输出三个队列的内容
void outfile();//输出三个队列的内容到相应文件中
FILE *fp;//文件
int wordcount;//标志符计数
int numcount;//整型常数计数
int err;//标志词法分析结果正确或错误
int nl;//读取行数
……………………………………

8421(游客)发表评论于2006-1-6 14:37:45

设计题目
1、  单词识别(必选)
*C语言常数
*C语言标识符
2、  程序文本的处理(必选)
*将C程序中的所有注释字母军大写
*将C语言注释之外的所有保留字全部大写
3、  程序实现(选做1个)
*简单语言词法分析器的状态转换图(P43)
*递归下降语法分析(P74)
各位大哥 这是我们的编译原理课设要求,那位大哥帮帮小弟阿
以下为blog主人的回复:
相应程序请参考blog左上角程序下载链接。

哦(游客)发表评论于2005-12-12 16:16:48

我看不太懂 以下为blog主人的回复:
词法分析功能其实就是分类和转化

子圆(游客)发表评论于2005-11-25 9:04:46

各位高手,这是我们的实验课,但不是很懂啊,请大家帮帮忙吧!!非常感谢!!!
题目是:给出pascal程序语言文法如下:s——if  B then  S else S  |while B do S |begin L   end| A
L——S;L|S     A——i:=E      B——B ^B|B V B| > B|i rop i|I   E——E+E|E*E| (E)|I
其中rop代表关系运算符>,>=,<,<=,==,<>    ^表示逻辑与   V表示逻辑或   >表示逻辑非  ——表示推出符号
要求:写出单词种别编码,并给出原程序。

以下为blog主人的回复:
要求写出编码,好象只是词法分析啊。其实词法分析就是一个映射的思想,没什么难的,语法分析要保证语法的正确性,然后采取合适的语法分析方法(算符优先、slr、lr等)来做,语义分析就是回过头来在语法分析的同时加一些东西。至于原程序嘛,最终还是要自己去写的哦。不管语法简单或难,原理都是一样的,只要你思想明白了,剩下的就是体力劳动了,只是时间多一点罢了,不可能做不出来的。

Mark(游客)发表评论于2005-10-20 18:45:07

下面的代码用c#写的,制作很小的改动就可用于C实现了,只是为了交流一下,语法分析器等我昨晚后也会贴上来的。
  另外,本来这个程序是有图形界面的,用VS .net开发的,但是这里回复不了附件,需要的话email给我。地址见代码。
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace CCompiler
{
/// <summary>
/// 词法分析的核心,读入输入文件,词法分析后将结果(符号表)
/// 及错误输出到文件。
///Author :MarK@hit
///Date:2005-10
///mailto:symphnoy@163.com
/// </summary>
public class Lexer :System.Object
{
  #region 类属性/成员列表
  private int LineNO;//保留当前的行号
  private int lastbyte;//判断最后一个字符,主要用于处理文件结尾:
  private  System.Collections.ArrayList KeyWords;//关键字列表,存在数组里以便查表。
  private  System.Collections.ArrayList ErrorList;//错误列表。
  private  System.IO.TextReader  inputReader;
  public   System.IO.StreamWriter  outputWriter;
  private static char  EOF=System.Convert.ToChar(255);//定义文件结尾,以便能被Char型表示。
  #endregion
  /// <summary>
  /// Lexer的构造函数
  /// </summary>
  /// <param name="input"></param>
  /// <param name="output"></param>
  public Lexer(string input,string output)
  {
   KeyWords = new ArrayList(30);
   ErrorList = new ArrayList(40);
   LineNO=1;
   this.FillUpKeyWords();
   try
   {
    //初始化输入输出流
    inputReader= new System.IO.StreamReader(input,System.Text.Encoding.ASCII);
    outputWriter=new System.IO.StreamWriter(output,false,System.Text.Encoding.ASCII);
    this.outputWriter.Write("\n\t\t\t%%%Lexical Analysis Beginning:%%%\t\n");
    this.outputWriter.Write("=========================================================================\n");
   }
   catch(System.Exception excp)
   {
    this.ErrorReport(excp.Message+"\n\n"+excp.HelpLink,"IO Exception @ Lexical Analysis");
   }
  }
  #region 调试的主函数,可以使LexerCore运行在cmd下脱离界面
  //  [STAThread]
  //  static void Main(string[] args)
  //  {
  //   Lexer lex = new Lexer("input.txt","output.txt");
  //   int i=lex.DoLexicalAnalysis();
  //   System.Console.WriteLine("Finished!");
  //   if(i==0)
  //    Application.Exit();
  //   //
  //   // TODO: 在此处添加代码以启动应用程序
  //   //
  //  }
  #endregion
  /// <summary>
  /// 初始化关键字/保留字列表
  /// </summary>
  private void FillUpKeyWords()
  {
   this.KeyWords.Add("auto");
   this.KeyWords.Add("break");
   this.KeyWords.Add("case");
   this.KeyWords.Add("char");
   this.KeyWords.Add("const");
   this.KeyWords.Add("continue");
   this.KeyWords.Add("default");
   this.KeyWords.Add("do");
   this.KeyWords.Add("double");
   this.KeyWords.Add("else");
   this.KeyWords.Add("enum");
   this.KeyWords.Add("extern");
   this.KeyWords.Add("float");
   this.KeyWords.Add("for");
   this.KeyWords.Add("goto");
   this.KeyWords.Add("if");
   this.KeyWords.Add("int");
   this.KeyWords.Add("long");
   this.KeyWords.Add("register");
   this.KeyWords.Add("return");
   this.KeyWords.Add("short");
   this.KeyWords.Add("signed");
   this.KeyWords.Add("sizeof");
   this.KeyWords.Add("static");
   this.KeyWords.Add("struct");
   this.KeyWords.Add("switch");
   this.KeyWords.Add("typedef");
   this.KeyWords.Add("union");
   this.KeyWords.Add("usigned");
   this.KeyWords.Add("void");
   this.KeyWords.Add("volatile");
   this.KeyWords.Add("while");
  }
  private void ErrorReport(System.String msg,System.String title)
  {
   MessageBox.Show(msg,title,System.Windows.Forms.MessageBoxButtons.OK,System.Windows.Forms.MessageBoxIcon.Error);
  }
  /// <summary>
  /// 分析完成后将错误消息队列里的信息依次输出
  /// </summary>
  private void ErrorReport()
  {
   this.ErrorList.TrimToSize();
   int errorno=this.ErrorList.Count;
   for(int i=0;i<errorno;i++)
   {
    this.outputWriter.WriteLine("Error No:"+i+"\t"+this.ErrorList);
   }
  }
  private void SaveError(System.String msg,int lineno)
  {
   this.ErrorList.Add(msg+"@"+lineno);
  }
  /// <summary>
  /// getchar:一个完全没有必要的函数
  /// 这么做只是为了象底层C一样的编程,否则直接用Regexp类构造好了
  /// </summary>
  /// <returns></returns>
  private char getchar()
  {
   try
   {
    lastbyte=inputReader.Read();
    return System.Convert.ToChar(lastbyte);
   }
   catch(System.OverflowException expc)
   {
    if(lastbyte==-1)
     return EOF;
    else
    {
     this.SaveError(expc.ToString()+"\n\tThe Value for the InputSteam Is "+lastbyte,0);
     return System.Convert.ToChar(lastbyte);
    }

   }
  }
  private void FormatPrint(string type,int count,char[] token,int i)
  {

   try
   {
    this.outputWriter.WriteLine(type+"\t\t\t"+count+"\t\t"+new System.String(token,0,i)+"\t\t"+i+"\t@Ln:"+this.LineNO);
   }
   catch(System.Exception expc)
   {

    String errormsg=expc.Message.ToString()+"\nStackTrace:\t\n"+expc.StackTrace.ToString();
    this.outputWriter.WriteLine(errormsg);
    MessageBox.Show(errormsg,
     "Exception During FormatPrint,at:"+expc.Source,System.Windows.Forms.MessageBoxButtons.OK,System.Windows.Forms.MessageBoxIcon.Error);
   }
   finally
   {
    //this.outputWriter.Close();
   }
  }
  ///
  ///<summary>
  ///词法分析核心部分
  ///</summary>
  ///
  public  int DoLexicalAnalysis()
  {
   char ch;//,*token="";
   char[] token= new char[10000];
   int i=0,isReserver=0;
   int count=0;

   this.outputWriter.WriteLine("Type \t\t Count \t\t Symbol \t\t Lenth\n");
   try
   {
    #region 词法分析循环过程,亦是状态机控制流程
    ch=getchar();
    while(ch!=EOF)
    {
     i=0;
     /*去掉空格,换行符*/
     while((ch==' '||ch=='\n'||ch=='\t')&&ch!=EOF)
     {
      if(ch=='\n')
      this.LineNO++;
      ch=getchar();
     }
     /*字母开头*/
     if(Char.IsLetter(ch))
     {
      while(Char.IsLetterOrDigit(ch))
      {
       token[i++]=ch;
       ch=getchar();
      }
      token='';
      isReserver=this.IsReserver(token,i);
      if(isReserver==1)
      {count++;this.FormatPrint("Identifer",count,token,i);}
      else if(isReserver==0)
      {count++;this.FormatPrint("KeyWord",count,token,i);}
      else if(isReserver==2)
      {count++;this.FormatPrint("Operator",count,token,i);}
      continue;
     }
      /*识别数字*/
     else if(Char.IsDigit(ch))
     {
      while(Char.IsDigit(ch))
      {
       token[i++]=ch;
       ch=getchar();
      }
      /*出现非数字且为点时*/
      if (ch=='.')
      {
       token[i++]=ch; /*将点加入*/
       ch=getchar();/*读入下一个字符*/
       if (Char.IsDigit(ch))
       {
        while(Char.IsDigit(ch)) /*是数字时,收入,并将加一*/
        {
         token[i++]=ch;
         ch=getchar();
        }
        /*如果是数字加点再加数字再出现字母时,就是错误*/
        if(Char.IsLetter(ch))
        {
         while(Char.IsDigit(ch)||Char.IsLetter(ch)||ch=='.')
         {
          token[i++]=ch;
          ch=getchar();
         }
         token='';
         count++;this.FormatPrint("IdentiferError",count,token,i);
         continue;
        }
         /*当出现结束符时,就收入为实数内*/
        else
        {
         token='';
         count++;this.FormatPrint("RealNumber",count,token,i);
         continue;
        }
       }
      }

       /*如果是字符,则判断为标识错误*/
      else if(Char.IsDigit(ch))
      {
       while(Char.IsDigit(ch)||Char.IsDigit(ch)||ch=='.')
       {
        token[i++]=ch;
        ch=getchar();
       }
       token='';
       count++;this.FormatPrint("IdentiferError",count,token,i);
       continue;
      }
       /*如果是单词段结束符时,就判断为常数*/
      else
      {
       token='';
       count++;this.FormatPrint("Interger",count,token,i);
       continue;
      }
     }
     else if(ch=='(')
     {
      token[i++]=ch;
      ch=getchar();
      token='';
      count++;this.FormatPrint("Parenleft",count,token,i);
      continue;
     }
     else if(ch==')')
     {
      token[i++]=ch;
      ch=getchar();
      token='';
      count++;this.FormatPrint("Parenright",count,token,i);
      continue;
     }
     else if(ch=='[')
     {
      token[i++]=ch;
      ch=getchar();
      token='';
      count++;this.FormatPrint("Bracketlef",count,token,i);
      continue;
     }
     else if(ch==']')
     {
      token[i++]=ch;
      ch=getchar();
      token='';
      count++;this.FormatPrint("Bracketright",count,token,i);
      continue;
     }
     else if(ch=='-')
     {
      token[i++]=ch;
      ch=getchar();
      if(ch=='-')
      {
       token[i++]=ch;
       token='';
       count++;this.FormatPrint("AutoMinusOperator",count,token,i);
       ch=getchar();
       continue;
      }
      else if (ch=='>')
      {
       token[i++]=ch;
       token='';
       count++;this.FormatPrint("PointerOperator",count,token,i);
       ch=getchar();
       continue;
      }
      token='';
      count++;this.FormatPrint("NegativeOperator",count,token,i);
      continue;
     }
     else if(ch=='.')
     {
      token[i++]=ch;
      ch=getchar();
      token='';
      count++;this.FormatPrint("DotOperator",count,token,i);
      continue;
     }
     else if(ch=='&')
     {
      token[i++]=ch;
      ch=getchar();
      token='';
      count++;this.FormatPrint("BitAnd",count,token,i);
      continue;
     }
     else if(ch=='!')
     {
      token[i++]=ch;
      ch=getchar();
      if(ch=='=')
      {
       token[i++]=ch;
       token='';
       count++;this.FormatPrint("UnequalComparator",count,token,i);
       ch=getchar();
       continue;
      }
      token='';
      count++;this.FormatPrint("NotOperator",count,token,i);
      continue;
     }
     else if(ch=='~')
     {
      token[i++]=ch;
      ch=getchar();
      token='';
      count++;this.FormatPrint("Tilde",count,token,i);
      continue;
     }
     else if(ch=='*')
     {
      token[i++]=ch;
      ch=getchar();
      token='';
      count++;this.FormatPrint("MutiplyOperator",count,token,i);
      continue;
     }
     else if(ch=='%')
     {
      token[i++]=ch;
      ch=getchar();
      token='';
      count++;this.FormatPrint("ModOperator",count,token,i);
      continue;
     }
     else if(ch=='/')
     {

      //String
      token[i++]=ch;
      ch=getchar();
      if(ch!='/'&&ch!='*')
      {
       token='';
       count++;
       this.FormatPrint("DivOperator",count,token,i);
       continue;
      }
      else if(ch=='/')
      {
       //忽略行注视
       this.inputReader.ReadLine();
       this.LineNO++;
       continue;
      }
      else
      {
       //忽略/**/注释
       while(ch!='*'&&ch!=EOF)
       {
        if(ch=='\n')
        this.LineNO++;
        token[i++]=ch;
        ch=getchar();
       }
       while(ch!='/'&&ch!=EOF)
       {
        if(ch=='\n')
        this.LineNO++;
        token[i++]=ch;
        ch=getchar();
       }
       continue;
      }
     }
     else if(ch=='<')
     {
      token[i++]=ch;
      ch=getchar();
      if(ch=='=')
      {
       token[i++]=ch;
       token='';
       count++;this.FormatPrint("LessEqual",count,token,i);
       ch=getchar();
       continue;
      }
      if(ch=='<')
      {
       token[i++]=ch;
       token='';
       count++;this.FormatPrint("LeftShift",count,token,i);
       ch=getchar();
       continue;
      }
      token='';
      count++;this.FormatPrint("Lessthan",count,token,i);
      continue;
     }
     else if(ch=='>')
     {
      token[i++]=ch;
      ch=getchar();
      if(ch=='=')
      {
       token[i++]=ch;
       token='';
       count++;this.FormatPrint("Greaterthan",count,token,i);
       ch=getchar();
       continue;
      }
      if(ch=='>')
      {
       token[i++]=ch;
       token='';
       count++;this.FormatPrint("RightShift",count,token,i);
       ch=getchar();
       continue;
      }
      token='';
      count++;this.FormatPrint("Greaterthan",count,token,i);
      continue;
     }
     else if(ch=='=')
     {
      token[i++]=ch;
      ch=getchar();
      if(ch=='=')
      {
       token[i++]=ch;
       token='';
       count++;this.FormatPrint("Equals",count,token,i);
       ch=getchar();
       continue;
      }
      token='';
      count++;this.FormatPrint("Evaluator",count,token,i);
      continue;
     }
     else if(ch==',')
     {
      token[i++]=ch;
      ch=getchar();
      token='';
      count++;this.FormatPrint("Comma",count,token,i);
      continue;
     }
     else if(ch==';')
     {
      token[i++]=ch;
      ch=getchar();
      token='';
      count++;this.FormatPrint("Semicolon",count,token,i);
      continue;
     }
     else if(ch=='{')
     {
      token[i++]=ch;
      ch=getchar();
      token='';
      count++;this.FormatPrint("Braceleft",count,token,i);
      continue;
     }
     else if(ch=='}')
     {
      token[i++]=ch;
      ch=getchar();
      token='';
      count++;this.FormatPrint("Braceright",count,token,i);
      continue;
     }
     else if(ch=='+')
     {
      token[i++]=ch;
      ch=getchar();
      if(ch=='+')
      {
       token[i++]=ch;
       token='';
       count++;this.FormatPrint("PlusPlus",count,token,i);
       ch=getchar();
       continue;
      }
      token='';
      count++;this.FormatPrint("Plus",count,token,i);
      continue;
     }
     else if(ch=='\'')
     {
      token[i++]=ch;
      ch=getchar();
      while(ch!='\''&&ch!=EOF)
      {
       token[i++]=ch;
       ch=getchar();
      }
      if(ch=='\'')
      {
       token[i++]=ch;
       ch=getchar();
       token='';
       count++;
       this.FormatPrint("Char",count,token,i);
       continue;
      }
      else
      {
       while(ch!=EOF)
       {
        token[i++]=ch;
        ch=getchar();
       }
       token='';
       count++;this.SaveError("Char Error:",this.LineNO);
      }
     }
     else if(ch=='"')
     { //String
      token[i++]=ch;
      ch=getchar();
      while(ch!='"'&&ch!=EOF)
      {
       token[i++]=ch;
       ch=getchar();
      }
      if(ch=='"')
      {
       token[i++]=ch;
       ch=getchar();
       token='';
       count++;this.FormatPrint("String",count,token,i);
       continue;
      }
      else
      {
       while(ch!=EOF)
       {
        token[i++]=ch;
        ch=getchar();
       }
       token='';
       count++;this.SaveError("String Error:",this.LineNO);
      }
     }
     else
     {
      while(!(ch==' '||ch=='\t'||ch=='\n'||ch==EOF))
      {
       count++;
       if(!(System.Convert.ToInt16(ch)==10||System.Convert.ToInt16(ch)==13))
        this.SaveError("Unknown Symbol:",this.LineNO);
       token[i++]=ch;
       ch=getchar();
      }
      token='';
      count++;
      if(!(System.Convert.ToInt16(ch)==10||System.Convert.ToInt16(ch)==13))
       this.SaveError("Unknown Error:",this.LineNO);
      continue;
     }
    }
    #endregion
   }
   catch(System.Exception expc)
   {
    String errormsg=expc.ToString();
    this.SaveError(errormsg,-1);
    ErrorReport();//报告词法分析过程中出现的任何可能错误
    this.inputReader.Close();
    this.outputWriter.Close();
    return 1;
   }
   ErrorReport();
   this.inputReader.Close();
   this.outputWriter.Close();
   return 0;
  }
  /// <summary>
  /// 判断是不是C的保留字
  /// </summary>
  /// <param name="token"></param>
  /// <param name="lenth"></param>
  /// <returns>
  ///  1:则是标识符
  ///  0:则是关键字
  ///  2:则是运算符--sizeof
  ///  </returns>
  /**************************************************************
  *  判断是不是关键字:1,则是标识符 0,则是关键字 2,则是运算符
  **************************************************************/
  private int IsReserver(char[] token,int lenth)
  {
   System.String str = new string(token,0,lenth);
   if(System.String.Compare(str,"sizeof")==0)  return 2;
   if(this.KeyWords.Contains(str)==true) return 0;
   return 1;
  }

}
}

以下为blog主人的回复:
恩,欢迎欢迎,如果愿意的话,把程序发给我,我给你传上去,供大家分享.我的邮箱是ivan@panshi.org

芋头(游客)发表评论于2005-10-16 21:31:34

感谢啊...我也是哈尔滨的.不过是黑大了......
现在正在弄编译大作业,一头雾水,实在不会啊......谢谢你的程序....简直是大好人啊........我下了回去好好学学....

hukuna(游客)发表评论于2005-10-14 21:01:37

第一次到你这个blog来,是搜到的
我要做编译课设,但是我学得很差劲,以至于题目都看不懂(寒),你能不能帮我分析一下,我自己写就好了。
题目是这样的:1.实现适合于c-的一个符号表,要求表结构接合作用域信息,用于当各个独立的表连接到一气,或者有一个删除机制,用于基于栈方式的操作。
2.实现一个c-扫描器,或者象DFA用手工进行,或者使用LEX
3.设计一个C-语法树结构,适合于用分析器产生
4.实现一个C-分析器(这需要一个C-扫描器),或者使用递归下降用收工进行,或者使用YACC,分析器要产生合适的语法树。
第一个要求偶不太懂,符号表接合作用域信息用于各个独立的表链接到一起,什么意思呢?
然后是第三个,设计语法树结构是什么意思?
你会不会在啊,有空回答一下,谢谢了。
以下为blog主人的回复:
说实在的,现在正在准备考研,把不相关的东西都忘的差不多了,编译原理的印象也不是很清晰啦
然后说你的问题:如果完全按照这个要求做,太难了,或者是不太可能做出来的,如果在本科阶段能独立的做出一个C编译器,那真的是很牛啊,所以建议你把要求中所有的C改为类C.至于你说的第一条,我也弄不明白,因为我断句都不知道怎么断.第三条其实是和写程序无关的,只是编译原理的思想,你可以把它画在草图上;语法分析的过程,就是一个建立一个语法树的过程,如果扫描的最后能成为一棵树,则证明源程序语法是没有问题的,否则语法分析阶段就要报错.所谓的自上而下,自下而上就是对于树来说的,但从程序上看,没有任何数据结构里"树"的意思.而语义分析阶段你会发现是和语法分析同时进行的.所以第三条的要求不是叫你用树的结构来做,而是提醒你这种思想,它不说你也要用的.不知道解释的是否清楚.看看书吧,能理解的更透彻的.

wxrsun(游客)发表评论于2005-8-22 15:40:19

你也是哈工大的啊,我也是,可惜是在威海 以下为blog主人的回复:
呵呵,校友好啊

飞飞(游客)发表评论于2005-6-22 12:50:36

能不能再帮我做一个啊?要求不太一样的哦 以下为blog主人的回复:
现在正处于考试时间,刚刚把编译原理语义的部分完成,也就是这个学期的大作业(词法,语法,语义)全部完工了.但是报告还得再找时间去做,我现在只能帖出来让大家参考,如果能有时间帮大家做更多的事,也只能是在考试完之后了.
整个简单编译器的前端,到产生中间代码,我会在报告完全写好之后传上来,估计是下周,呵呵

还有呢(游客)发表评论于2005-6-21 8:23:13
怎么就这么一点呀~
以下为blog主人的回复:
这里显示的只是程序的很少一段代码,可以点击上面的"请点击这里下载“词法分析器”源程序"来下载

佩服(游客)发表评论于2005-5-31 19:08:18

强人啊 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!