首页 > 其他分享 >pl0词法分析器

pl0词法分析器

时间:2024-04-28 13:56:40浏览次数:26  
标签:---- ch pl0 syn 分析器 词法 token 25 break

pl/0词法分析器

下面是这个分析器的功能:

1、 待分析的简单语言的词法

(1) 关键字:

begin if then while do end

所有关键字都是小写。

(2) 运算符和界符:

:= + – * / < <= <> > >= = ; ( ) #

(3) 其他单词是标识符(ID)和整型常数(NUM),通过以下正规式定义:

ID=letter(letter| digit)*

NUM=digit digit *

(4) 空格由空白、制表符和换行符组成。空格一般用来分隔ID、NUM,运算符、界符和关键字,词法分析阶段通常被忽略。

2、 各种单词符号对应的种别码

词法分析程序的功能

输入:所给文法的源程序字符串。

输出:二元组(syn,token或sum)构成的序列。

其中:syn为单词种别码;

token为存放的单词自身字符串;

sum为整型常数。

#include <iostream>

#include <fstream>

#include <string>

#include <windows.h>

 

using namespace std;

 

#define CODE "E:\\code\\code.txt"

#define RESULT "E:\\code\\result.txt"

 

//token数组用来接收关键字,变量,运算符和界符

//这里限制变量名的长度最多为9

//prog数组存储的是源代码字符串长度

char *prog, token[10];

char ch;

//syn是各个单词符号对应的数字

int syn, p, m = 0, n, line, sum = 0;

//rwtab数组存储的是关键字

char *rwtab1[10] = { "begin","if","then","while","do","end" };

char *rwtab2[4] = { "const","var","procedure","call" };

 

void scaner()

{

//规定,标识符只能由字母或数字构成

 

/*

共分为三大块,分别是标示符、数字、符号,对应下面的 if else if 和 else

*/

 

//将全部置空

for (n = 0; n<10; n++)

//token为已捕获的字符数

token[n] = NULL;

ch = prog[p++];

 

//这样处理,可以去除空格

while (ch == ' ')

{

ch = prog[p];

p++;

}

//在这个if判断中,范围是a-z或者A-Z,因为规定变量只能以字母开头

if ((ch >= 'a'&&ch <= 'z') || (ch >= 'A'&&ch <= 'Z')) //可能是标示符或者变量名

{

m = 0;

//这里,是变量的第一个字符以后,可以是字母,数字

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

{

token[m++] = ch;

ch = prog[p++];

}

//变量的字符串结束标志

token[m++] = '\0';

p--;

syn = 10;

 

//将识别出来的字符和已定义的标示符作比较, 判断是否是关键字,所有关键字都是小写

for (n = 0; n<6; n++)

if (strcmp(token, rwtab1[n]) == 0)

{

syn = n + 1;

break;

}

for (n = 0; n < 4;n++)

{

if (strcmp(token, rwtab2[n]) == 0)

{

syn = n + 31;

break;

}

}

}

else if ((ch >= '0'&&ch <= '9')) //数字 ,如果是数字,就用sum来保存这个数字

{

sum = 0;

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

{

//这里*10是只考虑十进制数

sum = sum * 10 + ch - '0';

ch = prog[p++];

}

p--;

syn = 11;

//可接收的数字的最大值为32767,如果更大,会报错

if (sum>32767)

syn = -1;

}

else switch (ch) //如果是其他的字符

{

case '<':

m = 0;

token[m++] = ch;

ch = prog[p++];

if (ch == '>')

{

//说明是不等号

syn = 21;

token[m++] = ch;

}

else if (ch == '=')

{

//说明是<=

syn = 22;

token[m++] = ch;

}

else

{

//否则,就只是一个<符号

syn = 23;

//此时p回退一个

p--;

}

break;

case '>':

m = 0;

token[m++] = ch;

ch = prog[p++];

if (ch == '=')

{

syn = 24;

token[m++] = ch;

}

else

{

syn = 20;

p--;

}

break;

case ':':

m = 0;

token[m++] = ch;

ch = prog[p++];

if (ch == '=')

{

//说明是赋值运算符

syn = 18;

token[m++] = ch;

}

else

{

//否则就只是个:

syn = 17;

p--;

}

break;

case '*':

syn = 13;

token[0] = ch;

break;

case '/':

syn = 14;

token[0] = ch;

break;

case '+':

syn = 15;

token[0] = ch;

break;

case '-':

syn = 16;

token[0] = ch;

break;

case '=':

syn = 25;

token[0] = ch;

break;

case ';':

syn = 26;

token[0] = ch;

break;

case '(':

syn = 27;

token[0] = ch;

break;

case ')':

syn = 28;

token[0] = ch;

break;

case ',':

syn = 29;

token[0] = ch;

break;

case '!':

syn = 30;

token[0] = ch;

break;

case '.':

//如果接收到的是.,说明到了源代码的结尾,置syn=0,函数结束

syn = 0;

token[0] = ch;

break;

case '\n':

//如果接收到的是换行符,则syn=-2,行+1

syn = -2;

break;

default:

//如果接收到的是其他未定义的字符,置syn=-1,会报错。

syn = -1;

break;

}

}

 

/*

读取源代码文件(.txt)

*/

void read()

{

FILE *fp;

fp = fopen(CODE, "r");

fseek(fp, 0, SEEK_END);

int file_size;

file_size = ftell(fp);

fseek(fp, 0, SEEK_SET);

prog = (char *)malloc(file_size * sizeof(char));

fread(prog, file_size, sizeof(char), fp);

 

//关闭文件流

fclose(fp);

}

 

int main()

{

int p = 0;

int line = 1;

ofstream outfile(RESULT);

 

cout<< "加载代码文件中......" << endl;

Sleep(3000);

//读取源代码文件

read();

 

p = 0;

outfile << "词法分析的结果为:" << endl;

do

{

scaner();

switch (syn)

{

case 11:

//cout << "(" << syn << "," << sum << ")" << endl;

outfile << "(" << syn << "," << sum << ")" << endl;

break;

case -1:

//cout << "Error in line " << line << "!" << endl;

outfile << "Error in line" << line << "!" << endl;

break;

case -2:

line = line++;

break;

default:

//cout << "(" << syn << "," << token << ")" << endl;

outfile << "(" << syn << "," << token << ")" << endl;

break;

}

} while (syn != 0);

 

outfile.close();

 

cout << "词法分析完毕,请在result.txt中查看" << endl;

 

system("pause");

return 0;

}

pl/0 程序

var m, n, r, q;

procedure gcd;

begin

while r#0 do

begin

q := m / n;

r := m - q * n;

m := n;

n := r;

end;

end;

begin

read(m);

read(n);

if m < n then

begin

r := m;

m := n;

n := r;

end;

begin

r:=1;

call gcd;

write(m);

end;

end.

输出结果

#

#

using---->25

namespace---->25

std---->25

;------->41

int---->7

main---->1

(------->42

)------->43

const---->18

string---->25

str---->25

=------->38

hello---->25

;------->41

const---->18

string---->25

str2---->25

=------->38

world---->25

;------->41

string---->25

n_str---->25

;------->41

n_str---->25

=------->38

str---->25

;------->41

n_str---->25

+------->27

=------->38

str2---->25

;------->41

cout---->25

<------>33

<------>33

n_str---->25

<------>33

<------>33

endl---->25

;------->41

return---->17

0------>26

;------->41

————————————————

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

 

原文链接:https://blog.csdn.net/judyge/article/details/52274690

标签:----,ch,pl0,syn,分析器,词法,token,25,break
From: https://www.cnblogs.com/djcsch2001/p/18163603

相关文章

  • Elasticsearch 所有内置分析器介绍(5)
     Elasticsearch 附带了各种内置分析器,可以直接在任何索引中使用,而无需额外配置:1)标准分析器  StandardAnalyzer该分析器的文本分词规则是:过滤掉大多数标点符号来划分单词,通过Unicode文本分割算法,再转成小写的分词。支持删除常用的停用词(如:the,a......
  • Pycharm——安装mypy(静态分析器)
    pycharm安装mypymypy是一个静态分析器,为在程序运行前进行代码分析,解决数据类型不一致或数据类型错误的问题。安装插件添加mypy程序:找到自己的目录C:\Users\xuanyongjun\AppData\Roaming\Python\Python312\Scripts\mypy.exe实参:$FilePath$工作目录:$FileDir$使用......
  • Elasticsearch 创建自定义分析器(4)
    一.自定义分析器当内置分析器不能满足时,可以创建一个自定义分析器,自定义分析器(analyzer)由:1)0或多个charactcrfilter字符过滤器2) 1个tokenizer分词器,将文本切分为分词  3)0或多个tokenfilter令牌过滤器,是属于分词后再过......
  • Elasticsearch 配置内置分析器(3)
    一.内置分析器(analyzer)内置分析器无需任何配置即可直接使用,也支持配置选项来更改其行为。下面示例,分别使用了自定义分析器与内置分析器PUTmy-index-000001{"settings":{"analysis":{"analyzer":{"std_english":{#自定义分析......
  • Elasticsearch 配置与测试分析器 (2)
    一.配置文本分析器(Configuretextanalysis) 默认情况下,Elasticsearch使用standard分析器来进行文本分析,如果使用该分析器,则不用额外的配置。如果不满足,可以使用其它内置分析器,也可以创建自定义的分析器更好的控制,通常在生产实战中都是自定义分析器,方便更好扩展。 ......
  • 【编译原理】手工打造语法分析器
    重点:语法分析的原理递归下降算法(RecursiveDescentParsing)上下文无关文法(Context-freeGrammar,CFG)关键点:左递归问题深度遍历求值-后续遍历上一篇「词法分析器」将字符串拆分为了一个一个的token。本篇我们将token变成语法树。一、递归下降算法还是这个例子in......
  • 词法分析基础
    我们是袋鼠云数栈UED团队,致力于打造优秀的一站式数据中台产品。我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值。本文作者:奇铭什么是词法分析要弄清楚什么是词法分析,需要先搞清楚代码是如何执行的。高级编程语言的代码通常需要通过翻译才能被机器执行,而翻译......
  • C#词法分析自动生成器
    C#词法分析自动生成器前言在做编译原理实验时,要求使用自动生成器生成词法分析器,老师推荐的是用flex,但用flex只会生成C代码,自己项目用的又是C#,本来想使用C代码直接生成dll库并用C#调用,但非常麻烦。干脆找了个能生成C#代码的生成器。配置相关的生成器很多,但我能找到的且能成功......
  • Machine Learning机器学习之文本分析的词法分析、句法分析、语义分析(详细讲解)
    目录前言词法分析:词义消歧:句法分析:语义分析:文本分析应用1、文本分类:设计过程:代码实现:完整代码: 2、情感分析:总结博主介绍:✌专注于前后端、机器学习、人工智能应用领域开发的优质创作者、秉着互联网精神开源贡献精神,答疑解惑、坚持优质作品共享。本人是掘金/腾讯......
  • PL/SQL的词法单元
    目录字符集标识符分隔符注释oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645PL/SQL块中的每一条语句都必须以分号结束。一个SQL语句可以跨多行,但分号表示该语句的结束:一行中也可以有多条SQL语句,各语句之间以分号......