java实现snl语法分析_SNL文法的词法分析器
#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文法的词法分析器相关推荐
- java实现snl语法分析_使用antlr4及java实现snl语言的解释器
其实我对于antlr4的理解也仅限于那篇文章的范围,但那些内容对于我们实现一个SNL语言已是足够了. 简单说来,这是一个非常简单的结构化编程语言,它包含了一个编程语言应该有的最基本的东西,同时基本上不 ...
- snl递归语法java,对SNL语言的解释器实现尾递归优化
对于SNL语言解释器的内容可以参考我的前一篇文章<使用antlr4及java实现snl语言的解释器>.此文只讲一下"尾递归优化"是如何实现的--"尾递归优化& ...
- 使用antlr4及java实现snl语言的解释器
对于antlr4的基础使用,请参考我的前一篇文章<用antlr4来实现<按编译原理的思路设计的一个计算器>中的计算器>. 其实我对于antlr4的理解也仅限于那篇文章的范围,但 ...
- cobol和java区别,COBOL语法和文法(1)
REDEFINES 可以用不同的变量描述同一内存. 01 PART_RECODE USAGE DISPLAY 03 PART-TYPE PICTURE... 03 PART_TYPE_A. 05 PA ...
- java语法分析生成器,语法词法生成器
一.语法词法生成器 Flex 语法扫描器生成器 flex (fast lexical analyser generator) 是Lex的另一个替代品.它经常和自由软件Bison语法分析器生成器 一起使 ...
- 自顶向下语法分析方法
目录 自顶向下分析 上下文无关文法的特性 带回溯的自顶向下语法分析 引起回溯的原因 消除回溯与左递归 消除回溯 消除左递归 确定的自顶向下分析 LL 分析法(预测分析法) LL(K)LL(K)LL(K ...
- 【安全工具】浅谈编写Java代码审计工具
介绍 笔者是大四学生,初涉安全的萌新,如果文章有错误之处还请大佬指出! 最初考虑采用纯正则等方式匹配,但这种方式过于严格,程序员编写的代码有各种可能的组合 于是尝试自行实现Java词法分析和语法分析, ...
- 编译原理——词法分析器
采用java图形化界面编写了java语言的词法分析器,该分析器可识别所有java关键字.软件工程课程中编译原理实验. Keyword.jvav package org.kyc.test1;public ...
- antlr java_使用ANTLR和Java创建外部DSL
antlr java 在我以前的文章中,有一段时间我写了关于使用Java的内部DSL的文章. 在Martin Fowler撰写的< 领域特定语言 >一书中,他讨论了另一种称为外部DSL的D ...
最新文章
- ServiceLoader跟DriverManager使用总结
- JavaScript 基础,登录验证
- buu 篱笆墙的影子
- Class.isAssignableFrom(Class clz)与instanceof与Class.isInstance(Object obj) 的区别和联系
- k8s包管理器helm_kubernetes包管理神器-Helm
- python 3.9特性,开发者应该知道的Python 3.9新特性
- Redo Log 和Checkpoint not complete
- 上传github代码
- Android ContentProvider 使用介绍
- vue 下配置标题栏 title 图标及文字的具体步骤
- linux软件中心无法安eclipse,Ubuntu软件中心安装Eclipse无法启动的问题
- JSP学生综合评价管理系统sqlserver数据库myeclipse开发
- Mac 系统SourceTree 配置VSCode代码对比工具
- BigDATA面试题
- [转载]Geronimo 叛逆者,第 8 部分: 未来的 Apache Geronimo
- php接口统计,EKL PHP 调取_search接口查询登录统计
- python参数内存地址
- mysql表名可以用中文么_[急]MySQL中建表不能使用中文字段吗?解决思路
- 有测试狗狗好坏的软件吗,想要养狗的朋友们请一定看完全文,测试一下自己适不适合养狗 ​...
- crmeb电商系统源码
热门文章
- [数据结构]最小生成树
- HDU - 6252 Subway Chasing (差分约束)
- EXCEL实现回归分析
- 种植牙好不好?该怎么选择?
- 一级计算机ie浏览器使用操作,2012计算机等级考试一级高分考点:IE操作
- DirectX for DirectShow---Get Start
- “玩电脑”和“被电脑玩”
- 山东大学软件工程应用与实践——使用CUDA/GPU技术加速密码运算(第七周)
- 384. Shuffle an Array
- mess-cli : 一个前端微服务架构脚手架(beta版)