语言名为TINY

实例程序:

begin
var x,y:interger;
x:=;
read(x);
if y< then x:=x-y;
x:=x+y;
write(x);
end

TINY语言扫描程序的DFA:

代码

//ExplLexicalAnalyzer.h
#ifndef EXPLLEXICALANALYZER_H
#define EXPLLEXICALANALYZER_H #define MAXTOKENLEN 40
#define MAXRESERVED 13 typedef enum {
ENDFILE, ERROR,
IF, THEN, ELSE, END, REPEAT, UNTIL, READ, WRITE, VAR, BEGIN, INTEGER, DOUBLE, STRING,
ID, NUM,
ASSIGN, EQ, LT, PLUS, MINUS, TIMES, OVER, LPAREN, RPAREN, SEMI, COMMA, DEFINE
} TokenType; //typedef struct {
// TokenType kind;
// int row = -1;
// int column = -1;
// double value;
// std::string ID;
//} Token; TokenType getToken(void); #endif //LEARN_2_EXPLLEXICALANALYZER_H
 //ExplLexicalAnalyzer.cpp
#include <cstdio>
#include <iostream>
#include <fstream>
#include <cstring>
#include "ExplLexicalAnalyzer.h" using namespace std; typedef enum {
START, INASSIGN, INCOMMENT, INNUM, INID, DONE
} StateType; char tokenString[MAXTOKENLEN + ]; #define BUFLEN 256 static char lineBuf[BUFLEN];
static int linepos = ;
static int bufsize = ;
static int EOF_flag = false;
static string filename;
static fstream get;
static int lineno = ;
static int columnpos = ;
bool TraceScan = true;
StateType state; static struct {
const char *str;
TokenType tok;
} reservedWords[MAXRESERVED]
= {{"if", IF},
{"then", THEN},
{"else", ELSE},
{"end", END},
{"repeat", REPEAT},
{"until", UNTIL},
{"read", READ},
{"write", WRITE},
{"begin", BEGIN},
{"var", VAR},
{"interger", INTEGER},
{"double", DOUBLE},
{"string", STRING}}; static char
getNextChar() {
if (linepos >= bufsize) {
lineno = ;
if (state != START)
return ' ';
if (get.getline(lineBuf, BUFLEN - )) {
printf("%d: %s\n", columnpos++, lineBuf);
bufsize = (int) strlen(lineBuf);
linepos = ;
return lineBuf[linepos++];
} else {
return EOF;
}
} else return lineBuf[linepos++];
} static TokenType reservedLookup(char *s) {
int i;
for (i = ; i < MAXRESERVED; i++)
if (!strcmp(s, reservedWords[i].str))
return reservedWords[i].tok;
return ID;
} //退回一个字符
static void ungetNextChar(void) { if (!EOF_flag) linepos--; } //打印分析结果
void printToken(TokenType token, const char *tokenString) {
switch (token) {
case IF:
case THEN:
case ELSE:
case END:
case REPEAT:
case UNTIL:
case READ:
case WRITE:
case BEGIN:
case VAR:
case INTEGER:
case DOUBLE:
case STRING:
printf("reserved word: %s\n", tokenString);
break;
case DEFINE:
printf(":\n");
break;
case COMMA:
printf(",\n");
break;
case ASSIGN:
printf(":=\n");
break;
case LT:
printf("<\n");
break;
case EQ:
printf("=\n");
break;
case LPAREN:
printf("(\n");
break;
case RPAREN:
printf(")\n");
break;
case SEMI:
printf(";\n");
break;
case PLUS:
printf("+\n");
break;
case MINUS:
printf("-\n");
break;
case TIMES:
printf("*\n");
break;
case OVER:
printf("/\n");
break;
case ENDFILE:
break;
case NUM:
printf("NUM, val= %s\n", tokenString);
break;
case ID:
printf("ID, name= %s\n", tokenString);
break;
case ERROR:
printf("ERROR: %s\n", tokenString);
break;
default:
printf("Unknown token: %d\n", token);
}
} //词法分析
TokenType getToken(void) {
int tokenStringIndex = ;
TokenType currentToken;
state = START;
bool save;
while (state != DONE) {
char c = getNextChar();
save = true;
switch (state) {
case START:
if (isdigit(c))
state = INNUM;
else if (isalpha(c))
state = INID;
else if (c == ':')
state = INASSIGN;
else if ((c == ' ') || (c == '\t') || (c == '\n'))
save = false;
else if (c == '{') {
save = false;
state = INCOMMENT;
} else {
state = DONE;
switch (c) {
case EOF:
return ENDFILE;
case ',':
currentToken = COMMA;
break;
case '=':
currentToken = EQ;
break;
case '<':
currentToken = LT;
break;
case '+':
currentToken = PLUS;
break;
case '-':
currentToken = MINUS;
break;
case '*':
currentToken = TIMES;
break;
case '/':
currentToken = OVER;
break;
case '(':
currentToken = LPAREN;
break;
case ')':
currentToken = RPAREN;
break;
case ';':
currentToken = SEMI;
break;
default:
currentToken = ERROR;
break;
}
}
break;
case INCOMMENT:
save = false;
if (c == EOF) {
state = DONE;
currentToken = ENDFILE;
} else if (c == '}') state = START;
break;
case INASSIGN:
state = DONE;
if (c == '=')
currentToken = ASSIGN;
else {
currentToken = DEFINE;
ungetNextChar();
}
break;
case INNUM:
if (!isdigit(c)) {
ungetNextChar();
save = false;
state = DONE;
currentToken = NUM;
}
break;
case INID:
if (!isalpha(c)) {
tokenString[tokenStringIndex] = '\0';
if (!strcmp(tokenString, "begin") || !strcmp(tokenString, "end")) {
save = false;
state = DONE;
currentToken = ID;
break;
}
ungetNextChar();
save = false;
state = DONE;
currentToken = ID;
}
break;
case DONE:
break;
}
if ((save) && (tokenStringIndex <= MAXTOKENLEN) && (state != START && !isspace(c)))
tokenString[tokenStringIndex++] = c;
if (state == DONE) {
tokenString[tokenStringIndex] = '\0';
if (currentToken == ID)
currentToken = reservedLookup(tokenString);
}
}
if (TraceScan) {
printf("\t%d: ", lineno++);
printToken(currentToken, tokenString);
}
return currentToken;
} int
main() {
if (cin >> filename && filename == "q") {
filename = "......";
}
get.open(filename, ios::in);
while (getToken() != ENDFILE);
}

运行结果:

词法分析器--DFA(c++实现)的更多相关文章

  1. C# 词法分析器(五)转换 DFA

    系列导航 (一)词法分析介绍 (二)输入缓冲和代码定位 (三)正则表达式 (四)构造 NFA (五)转换 DFA (六)构造词法分析器 (七)总结 在上一篇文章中,已经得到了与正则表达式等价的 NFA ...

  2. 自动构造词法分析器的步骤——正规式转换为最小化DFA

    正规式-->最小化DFA 1.先把正则式-->NFA(非确定有穷自动机) 涉及一系列分解规则 2.再把NFA通过"子集构造法"-->DFA 通过子集构造法将NFA ...

  3. 求子串-KPM模式匹配-NFA/DFA

    求子串 数据结构中对串的5种最小操作子集:串赋值,串比较,求串长,串连接,求子串,其他操作均可在该子集上实现 数据结构中串的模式匹配 KPM模式匹配算法 基本的模式匹配算法 //求字串subStrin ...

  4. Atitit 词法分析器的设计最佳实践说明attilax总结

    Atitit 词法分析器的设计最佳实践说明attilax总结 1.1. 手写的优点:代码可读,对源代码中的各种错误给出友好的提示信息,用户体验高,1 1.2. 使用状态表比较简单,dfa比较麻烦1 1 ...

  5. C# 词法分析器(一)词法分析介绍 update 2014.1.8

    系列导航 (一)词法分析介绍 (二)输入缓冲和代码定位 (三)正则表达式 (四)构造 NFA (五)转换 DFA (六)构造词法分析器 (七)总结 虽然文章的标题是词法分析,但首先还是要从编译原理说开 ...

  6. C# 词法分析器(二)输入缓冲和代码定位

    系列导航 (一)词法分析介绍 (二)输入缓冲和代码定位 (三)正则表达式 (四)构造 NFA (五)转换 DFA (六)构造词法分析器 (七)总结 一.输入缓冲 在介绍如何进行词法分析之前,先来说说一 ...

  7. C# 词法分析器(三)正则表达式

    系列导航 (一)词法分析介绍 (二)输入缓冲和代码定位 (三)正则表达式 (四)构造 NFA (五)转换 DFA (六)构造词法分析器 (七)总结 正则表达式是一种描述词素的重要表示方法.虽然正则表达 ...

  8. C# 词法分析器(四)构造 NFA

    系列导航 (一)词法分析介绍 (二)输入缓冲和代码定位 (三)正则表达式 (四)构造 NFA (五)转换 DFA (六)构造词法分析器 (七)总结 有了上一节中得到的正则表达式,那么就可以用来构造 N ...

  9. C# 词法分析器(六)构造词法分析器

    系列导航 (一)词法分析介绍 (二)输入缓冲和代码定位 (三)正则表达式 (四)构造 NFA (五)转换 DFA (六)构造词法分析器 (七)总结 现在最核心的 DFA 已经成功构造出来了,最后一步就 ...

随机推荐

  1. BZOJ 3202 项链

    题目连接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3202 题意:一个项链由n个珠子组成.每个珠子有三个面,每个面上有一个数字,要求每个 ...

  2. Quartz实用二三事

    注意:本文项目使用的Quartz版本为2.2.1 一.关于Trigger Trigger tg = newTrigger().withIdentity("tg3", "g ...

  3. Date、String和Timestamp类型转换

    1.String与Date类型转换: 1.获取当前系统时间: Date date1 = new Date();   //获取系统当前时间 Calendar cal = Calendar.getInst ...

  4. VSFTP安全加固

    这几天在公司需要做基线安全,一直都没有经验,所以在网上找了一些,做来参考学习. vsftp配置详解 这里是对vsftp配置文件的详细解释,主要参考了<RedHat8.0网络服务>一书中&l ...

  5. centos vpn

    yum install ppp -y cd /usr/local/src wget http://dl.fedoraproject.org/pub/epel/7/x86_64/p/pptpd-1.4. ...

  6. jQuery:show()方法

    show()方法是jQuery的方法,功能是显示元素,参数是时间,单位是毫秒,例如: Html: <div class="one" id="one"> ...

  7. (转)Web自动化测试中的接口测试

    1.背景 1.1 Web程序中的接口 1.1.1 典型的Web设计架构 web是实现了基于网络通信的浏览器客户端与远程服务器进行交互的应用,通常包括两部分:web服务器和web客户端.web客户端的应 ...

  8. JavaWeb学习总结(四)—ServletConfig和ServletContext

    一.ServletConfig 1. ServletConfig介绍: ServletConfig是Servlet中的init()方法的参数类型,服务器会在调用init()方法时传递ServletCo ...

  9. wireshark使用教程

    Wireshark: https://www.wireshark.org/ 安装: apt-get install wireshark 教程: http://blog.csdn.net/leichel ...

  10. Android AIDL Service

    AIDL Service //跨进程调用Service    一个APK想调用另一个APK中的Service 如何实现AIDL //定义两个进程之间的通信接口 Demo1 传递简单数据 AidlSer ...