实验目的:
设计、编制并调试一个词法分析程序,加深对词法分析的理解。
实验要求:
处理关键字、运算符和界符、标识符和整形常数、空格。
程序功能:
输入:所给文法的源程序字符串
输出:二元组构成的序列。
设计思想:
根据运算符,界符,空格把原程序分开成一个个的单词解析。对一个单词,判断它是整形常数,或关键字,或标识符。对几个特殊的单词符号,需要用到自动机去处理,如“:”、“<”、“>”,因为它们可以是一些运算符的首字符。
实验心得:
首先要理解词法分析程序的目的,认真分析它需要处理的词法是怎样的,根据特点设计出相应的解析思想。然后在程序实现过程中,注意细节,尽量使程序结构化清晰,方便调试。
#include<cstdio>
#include<string>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
string pattern[10];
bool isnum(char s){
return s >= '0' && s <= '9';
}
bool ischar(char s){
return (s >= 'a' && s <= 'z') || (s >= 'A' && s <= 'Z') || isnum(s);
}
string word;
char s;
bool checknum(){
for(int i = 0;i < word.length();i++){
if(isnum(word[i]) == false) return false;
}
printf("(11,");
cout << word << ")" << endl;
return true;
}
bool checkid(){
if(isnum(word[0])) return false;
for(int i = 0;i < word.length();i++){
if(ischar(word[i]) == false) return false;
}
printf("(%d,",10);
cout << "'" << word << "')" << endl;
return true;
}
bool checkpattern(){
for(int i = 1;i <= 6;i++){
if(word == pattern[i]){
printf("(%d,",i);
cout << word << ")\n";
return true;
}
}
return false;
}
void divide(){
if(word.length() != 0){
if(checknum() || checkpattern() || checkid());
else cout << "ERROR!" << endl;
word.clear();
}
int kind = -1;
switch(s){
case '+': kind = 13;break;
case '-': kind = 14;break;
case '*': kind = 15;break;
case '/': kind = 16;break;
case '=': kind = 25;break;
case ';': kind = 26;break;
case '(': kind = 27;break;
case ')': kind = 28;break;
}
if(kind != -1) printf("(%d,%c)\n",kind,s);
}
void getnext(){
word.push_back(s);
}
void smaller(){
divide();
char next;
scanf("%c",&next);
switch(next){
case '>':printf("(21,<>)\n");break;
case '=':printf("(22,<=)\n");break;
case '\n':
case ' ':printf("(20,<)\n");break;
default:printf("(20,<)\n");word.push_back(next);
}
}
void bigger(){
divide();
char next;
scanf("%c",&next);
if(next == '='){
printf("(24,>=)\n");
}
else if(next == ' ' || next == '\n') printf("(23,>)\n");
else{
printf("(23,>)\n");
word.push_back(next);
}
}
void colon(){
divide();
char next;
scanf("%c",&next);
if(next == '='){
printf("(18,:=)\n");
}
else if(next == ' ' || next == '\n') printf("(17,:)\n");
else{
printf("(17,:)\n");
word.push_back(next);
}
}
int main(){
pattern[1] = "begin";pattern[2] = "if";pattern[3] = "then";
pattern[4] = "while";pattern[5] = "do";pattern[6] = "end";
word.clear();
while(scanf("%c",&s) && s != '#'){
switch(s){
case ' ':
case '\n':
case '+':
case '-':
case '*':
case '/':
case '=':
case ';':
case '(':
case ')': divide();break;
case '<': smaller();break;
case '>': bigger();break;
case ':': colon();break;
default: getnext();
}
}
return 0;
}