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

发表于

请点击这里下载“词法分析器”源程序

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<fstream>
#include<string>
#include<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

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