上午数逻实验想了6,7道水题和一个hard,可惜没实现完,明天一定AC了。
昨天的sell and but stock IV终于理解了可是还是没通过…
下午实现了
还剩一个List的和一个stack的hard没写…
晚上把编译原理的作业完成了,用lex实现了一个词法分析器,少实现了++和–,明天补上。
格式大致![第一段两个百分号之间是定义枚举类Kind来表示各词法单元类型,然后是声明后边要用到的函数
第二段是正则定义,定义了letter,num和id三种正则表达式。
下边就是具体读到这个地方的时候执行的操作,要自己写的基本只有id这个词法单元。
进入主函数,读入字符不用理会。
下边就是我们自己创建的符号表token结构体,一个全局变量符号表指针word_list和一个用来记录ID属性值的idNum全局变量。
之后就是包括搜索,插入(创建),以及deal函数用来处理遇到ID类型如何输出。
一个容易忽略的点就是创建token的时候不能name=yytext.
否则yytext这片空间变得时候name也跟着变了。
%{
/****************************************************************************
mylexer.l
ParserWizard generated Lex file.
Date: 2016年11月8日
****************************************************************************/
#pragma warning( disable : 4996)
enum Kind{
TYPE=0,
ID,NUM,LB,RB,LD,RD,ADD,SUB,MUL,DIV,EQUAL,MAIN,ASSIGN,OPERATOR,SEMICOLON,IF,FOR,ELSE,WHILE
};
int search(char*word);
int add_word(int type,char*word);
void deal(char*yytext);
#include<iostream>
using namespace std;
%}
/////////////////////////////////////////////////////////////////////////////
// declarations section
// lexical analyser name
%name mylexer
// 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
letter [A-Za-z]
num [0-9]
id (_|{letter})(_|{letter}|{num})*
%%
/////////////////////////////////////////////////////////////////////////////
// rules section
// place your Lex rules here
[\n\t ] ;
main { cout << "MAIN " << yytext << endl; }
int { cout << "TYPE " << yytext << endl; }
double { cout << "TYPE " << yytext << endl; }
char { cout << "TYPE " << yytext << endl; }
void { cout << "TYPE " << yytext << endl; }
if { cout << "IF " << yytext << endl; }
for { cout << "FOR " << yytext << endl; }
else { cout << "ELSE " << yytext << endl; }
while { cout << "WHILE " << yytext << endl; }
{id} {deal(yytext); }
{num}* {cout << "NUM " << yytext << " " << yytext << endl; }
\+ {cout << "ADD " << yytext << " " << endl; }
- {cout << "SUB " << yytext << " " << endl; }
\* {cout << "MUL " << yytext << " " << endl; }
\/ {cout << "DIV " << yytext << " " << endl; }
= {cout << "ASSIGN " << yytext << " " << endl; }
== {cout << "EQUAL " << yytext << " " << endl; }
\( { cout << "LD " << yytext << " " << endl; }
\) {cout << "RD " << yytext << " " << endl;}
\{ { cout << "LB " << yytext << " " << endl; }
\} {cout << "RB " << yytext << " " << endl; }
; {cout << "SEMICOLON " << yytext<< endl; }
%%
/////////////////////////////////////////////////////////////////////////////
// programs section
int main(void)
{
cout << "词素表:" << endl;
cout << "单词 词素 属性" << endl;
mylexer lexer;
freopen("C:\\Users\\lenovo\\Desktop\\text.txt", "r", stdin);
if (lexer.yycreate())
lexer.yylex();
return 0;
}
struct token
{
Kind kind;
char *name;
token*next;
int pos;
token(Kind k=TYPE,char*n=NULL,token *behind=NULL,int p=0){
kind=k;
name=new char[sizeof(n)+1];
strcpy_s(name,sizeof(n)+1,n);
next=behind;
pos=p;
}
};
token *word_list=NULL;
int idNum=0;
int search(char*word)
{
token *tmp=word_list;
for(;tmp!=NULL;tmp=tmp->next){
if(strcmp(tmp->name,word)==0)
return tmp->pos;
}
return -1;//not found
}
int add_word(Kind type,char*word)
{
if(search(word)!=-1)
return -1;
token* tmp=new token(type,word,NULL,idNum);
tmp->next=word_list;
word_list=tmp;
idNum+=1;
return 1;
}
void deal(char*yytext)
{
int i=0;
add_word(ID,yytext);
i=search(yytext);
cout << "ID " << yytext << " " << i << endl;
}