#define _CRT_SECURE_NO_WARNINGS

#include

#include

#include

#include

#include

using namespace std;

//token结构体

struct Token

{

Token(string str, int pos)

{

this->type = str;

this->pos = pos;

}

string type;

int pos;

};

vector IdTable;//全局变量,词法分析得到的标示符表

vector NbTable;//全局变量,词法分析得到的INTC值表

#define ERROR_INVALID_SYMBOL 1//宏定义错误:非法符号

#define NO_ERROR 0//宏定义:没有错误

int error = NO_ERROR;//全局变量,记录词法分析中的错误类型

/*

*判断字符是不是其他字符

*/

bool IsOther(char ch)

{

if (ch >= 'A'&&ch <= 'Z')

return false;

if (ch >= 'a'&&ch <= 'z')

return false;

if (ch >= '0'&&ch <= '9')

return false;

return true;

}

/*

*判断字符串是不是关键字

*/

bool IsKeyWord(string str)

{

if (str == "integer")

return true;

if (str == "char")

return true;

if (str == "program")

return true;

if (str == "array")

return true;

if (str == "of")

return true;

if (str == "record")

return true;

if (str == "end")

return true;

if (str == "var")

return true;

if (str == "procedure")

return true;

if (str == "begin")

return true;

if (str == "if")

return true;

if (str == "then")

return true;

if (str == "else")

return true;

if (str == "fi")

return true;

if (str == "while")

return true;

if (str == "do")

return true;

if (str == "endwh")

return true;

if (str == "read")

return true;

if (str == "write")

return true;

if (str == "return")

return true;

if (str == "type")

return true;

return false;

}

/*

*返回字符串在表中的位置,没有就加到最后,并返回下标

*/

int AddIdTable(string str)

{

for (int i = 0; i < IdTable.size(); i++)

{

if (str == IdTable[i])

return i;

}

IdTable.push_back(str);

return IdTable.size()-1;

}

/*

*返回数字在表中的位置,没有就加到最后,并返回下标

*/

int AddNbTable(string str)

{

int num = atoi(str.c_str());

for (int i = 0; i < NbTable.size(); i++)

{

if (num == NbTable[i])

return i;

}

NbTable.push_back(num);

return NbTable.size() - 1;

}

/*

*词法分析扫描程序,每次调用返回一个Token指针

*/

Token *Scanner(FILE *pf)

{

char ch = 0;

string tmpStr = "";

Token * pToken = NULL;

LS0://根据第一个字符确定程序走向

ch = fgetc(pf);

if (ch != EOF)

{

if ((ch >= 'A' &&ch <= 'Z') || (ch >= 'a' && ch <= 'z'))

goto LS1;

if (ch >= '0' &&ch <= '9')

goto LS2;

if (ch == '+')

goto LS3;

if (ch == '-')

goto LS4;

if (ch == '*')

goto LS5;

if (ch == '/')

goto LS6;

if (ch == '

goto LS7;

if (ch == ';')

goto LS8;

if (ch == ':')

goto LS9;

if (ch == ',')

goto LS10;

if (ch == '.')

goto LS11;

if (ch == '=')

goto LS12;

if (ch == '[')

goto LS13;

if (ch == ']')

goto LS14;

if (ch == '(')

goto LS15;

if (ch == ')')

goto LS16;

if (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t')

goto LS17;

goto LS18;

}

else

{

return NULL;

}

LS1://标示符和关键字

{

tmpStr += ch;

ch = fgetc(pf);

if ((ch >= 'A' &&ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' &&ch <= '9'))

goto LS1;

if (IsOther(ch))

{

ungetc(ch, pf);//把读到的字符放回到文件流中

if (IsKeyWord(tmpStr))

{

//关键字

pToken = new Token("$"+tmpStr,-1);

return pToken;

}

else

{

//不是关键字,是标示符

int pos = AddIdTable(tmpStr);

pToken = new Token("$id", pos);

return pToken;

}

}

}

LS2://数字

{

tmpStr += ch;

ch = fgetc(pf);

if (ch >= '0' &&ch <= '9')

goto LS2;

if (IsOther(ch))

{

ungetc(ch, pf);

int pos = AddNbTable(tmpStr);

pToken = new Token("$INTC", pos);

return pToken;

}

}

LS3://'+'

{

pToken = new Token("$+", -1);

return pToken;

}

LS4://'-'

{

pToken = new Token("$-", -1);

return pToken;

}

LS5://'*'

{

pToken = new Token("$*", -1);

return pToken;

}

LS6://'/'

{

pToken = new Token("$/", -1);

return pToken;

}

LS7://'

{

pToken = new Token("$

return pToken;

}

LS8://';'

{

pToken = new Token("$;", -1);

return pToken;

}

LS9://':'

{

ch = fgetc(pf);

if (ch == '=')

{

pToken = new Token("$:=", -1);

return pToken;

}

if (IsOther(ch))

{

error = ERROR_INVALID_SYMBOL;

printf("错误:“:”不是合法的符号\n");

return NULL;

}

}

LS10://','

{

pToken = new Token("$comma", -1);

return pToken;

}

LS11://'.'

{

pToken = new Token("$.", -1);

return pToken;

}

LS12://'='

{

pToken = new Token("$=", -1);

return pToken;

}

LS13://'['

{

pToken = new Token("$[", -1);

return pToken;

}

LS14://']'

{

pToken = new Token("$]", -1);

return pToken;

}

LS15://'('

{

pToken = new Token("$(", -1);

return pToken;

}

LS16://')'

{

pToken = new Token("$)", -1);

return pToken;

}

LS17://空白符

{

goto LS0;

}

LS18://other

{

error = ERROR_INVALID_SYMBOL;//设置全局变量error

printf("错误:含有非法符号( %c )\n", ch);//打印错误信息

return NULL;

}

}

/*

*主函数,如果argc大于等于2,argv[1]为源文件名,否则默认为snl.txt

*/

int main(int argc, char ** argv)

{

//设置源文件

string filename;

if (argc >= 2)

filename = argv[1];

else

filename = "snl.txt";

//打开源文件

FILE *pf = fopen(filename.c_str(),"r");

if (!pf)

{

printf("打开文件失败!\n");

return -1;

}

vector result;

Token * pToken = NULL;

while ((pToken = Scanner(pf)) != NULL)

{

result.push_back(*pToken);

delete pToken;

pToken = NULL;

}

fclose(pf);

if (error == NO_ERROR)

{

pf = fopen((filename + ".token").c_str(), "w+");

for (auto &iter : result)

{

if (iter.type == "$id" || iter.type == "$INTC")

{

printf("(%-10s, [%2d] )\n", iter.type.c_str(), iter.pos);

fprintf(pf, "(%s,[%d])\n", iter.type.c_str(), iter.pos);

}

else

{

printf("(%-10s, \" \" )\n", iter.type.c_str());

fprintf(pf, "(%s,\"\")\n", iter.type.c_str());

}

}

fclose(pf);

pf = fopen((filename + ".idtable").c_str(), "w+");

for (int i = 0; i < IdTable.size(); i++)

{

fprintf(pf, "%s\n", IdTable[i].c_str());

}

fclose(pf);

pf = fopen((filename + ".nbtable").c_str(), "w+");

for (int i = 0; i < NbTable.size(); i++)

{

fprintf(pf, "%d\n", NbTable[i]);

}

fclose(pf);

}

system("pause");

}

程序输出的是token序列,以及标示符表和字面值表

token表文件名称为 *.token文件

其他两个表在语法分析中用不到,生成文件名称分别为*.idtable和*.nbtable。

java实现snl语法分析_SNL文法的词法分析器相关推荐

  1. java实现snl语法分析_使用antlr4及java实现snl语言的解释器

    其实我对于antlr4的理解也仅限于那篇文章的范围,但那些内容对于我们实现一个SNL语言已是足够了. 简单说来,这是一个非常简单的结构化编程语言,它包含了一个编程语言应该有的最基本的东西,同时基本上不 ...

  2. snl递归语法java,对SNL语言的解释器实现尾递归优化

    对于SNL语言解释器的内容可以参考我的前一篇文章<使用antlr4及java实现snl语言的解释器>.此文只讲一下"尾递归优化"是如何实现的--"尾递归优化& ...

  3. 使用antlr4及java实现snl语言的解释器

    对于antlr4的基础使用,请参考我的前一篇文章<用antlr4来实现<按编译原理的思路设计的一个计算器>中的计算器>. 其实我对于antlr4的理解也仅限于那篇文章的范围,但 ...

  4. cobol和java区别,COBOL语法和文法(1)

    REDEFINES 可以用不同的变量描述同一内存. 01 PART_RECODE USAGE DISPLAY 03 PART-TYPE PICTURE... 03 PART_TYPE_A. 05 PA ...

  5. java语法分析生成器,语法词法生成器

    一.语法词法生成器 Flex 语法扫描器生成器 flex (fast lexical analyser generator) 是Lex的另一个替代品.它经常和自由软件Bison语法分析器生成器 一起使 ...

  6. 自顶向下语法分析方法

    目录 自顶向下分析 上下文无关文法的特性 带回溯的自顶向下语法分析 引起回溯的原因 消除回溯与左递归 消除回溯 消除左递归 确定的自顶向下分析 LL 分析法(预测分析法) LL(K)LL(K)LL(K ...

  7. 【安全工具】浅谈编写Java代码审计工具

    介绍 笔者是大四学生,初涉安全的萌新,如果文章有错误之处还请大佬指出! 最初考虑采用纯正则等方式匹配,但这种方式过于严格,程序员编写的代码有各种可能的组合 于是尝试自行实现Java词法分析和语法分析, ...

  8. 编译原理——词法分析器

    采用java图形化界面编写了java语言的词法分析器,该分析器可识别所有java关键字.软件工程课程中编译原理实验. Keyword.jvav package org.kyc.test1;public ...

  9. antlr java_使用ANTLR和Java创建外部DSL

    antlr java 在我以前的文章中,有一段时间我写了关于使用Java的内部DSL的文章. 在Martin Fowler撰写的< 领域特定语言 >一书中,他讨论了另一种称为外部DSL的D ...

最新文章

  1. ServiceLoader跟DriverManager使用总结
  2. JavaScript 基础,登录验证
  3. buu 篱笆墙的影子
  4. Class.isAssignableFrom(Class clz)与instanceof与Class.isInstance(Object obj) 的区别和联系
  5. k8s包管理器helm_kubernetes包管理神器-Helm
  6. python 3.9特性,开发者应该知道的Python 3.9新特性
  7. Redo Log 和Checkpoint not complete
  8. 上传github代码
  9. Android ContentProvider 使用介绍
  10. vue 下配置标题栏 title 图标及文字的具体步骤
  11. linux软件中心无法安eclipse,Ubuntu软件中心安装Eclipse无法启动的问题
  12. JSP学生综合评价管理系统sqlserver数据库myeclipse开发
  13. Mac 系统SourceTree 配置VSCode代码对比工具
  14. BigDATA面试题
  15. [转载]Geronimo 叛逆者,第 8 部分: 未来的 Apache Geronimo
  16. php接口统计,EKL PHP 调取_search接口查询登录统计
  17. python参数内存地址
  18. mysql表名可以用中文么_[急]MySQL中建表不能使用中文字段吗?解决思路
  19. 有测试狗狗好坏的软件吗,想要养狗的朋友们请一定看完全文,测试一下自己适不适合养狗 ​...
  20. crmeb电商系统源码

热门文章

  1. [数据结构]最小生成树
  2. HDU - 6252 Subway Chasing (差分约束)
  3. EXCEL实现回归分析
  4. 种植牙好不好?该怎么选择?
  5. 一级计算机ie浏览器使用操作,2012计算机等级考试一级高分考点:IE操作
  6. DirectX for DirectShow---Get Start
  7. “玩电脑”和“被电脑玩”
  8. 山东大学软件工程应用与实践——使用CUDA/GPU技术加速密码运算(第七周)
  9. 384. Shuffle an Array
  10. mess-cli : 一个前端微服务架构脚手架(beta版)