前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >编译原理实验1词法分析器的设计_编译原理实验一 词法分析

编译原理实验1词法分析器的设计_编译原理实验一 词法分析

作者头像
全栈程序员站长
发布于 2022-11-19 09:40:31
发布于 2022-11-19 09:40:31
3.3K00
代码可运行
举报
运行总次数:0
代码可运行

大家好,又见面了,我是你们的朋友全栈君。

实验目的

  1. 掌握词法分析器的功能。
  2. 掌握词法分析器的实现。
  • 实验内容及要求

对于如下文法所定义的语言子集,试编写并上机调试一个词法分析程序:

<程序>→PROGRAM <标识符>;<分程序>.

<分程序>→<变量说明>BEGIN<语句表>END

<变量说明>→VAR<变量表>:<类型>;| <空>

<变量表>→<变量表>,<变量> | <变量>

<类型>→INTEGER

<语句表>→<语句表>;<语句> | <语句>

<语句>→<赋值语句> | <条件语句> | <WHILE语句> | <复合语句> | <过程定义>

<赋值语句>→<变量>:=<算术表达式>

<条件语句>→IF<关系表达式>THEN<语句>ELSE<语句>

<WHILE语句>→WHILE<关系表达式>DO<语句>

<复合语句>→BEGIN<语句表>END

<过程定义>→PROCEDURE<标识符><参数表>;

BEGIN<语句表>END

<参数表>→(<标识符表>)| <空>

<标识符表>→<标识符表>,<标识符> | <标识符>

<算术表达式>→<算术表达式>+<项> | <项>

<项>→<项>*<初等量> | <初等量>

<初等量>→(<算术表达式>)| <变量> | <无符号数>

<关系表达式>→<算术表达式><关系符><算术表达式>

<变量>→<标识符>

<标识符>→<标识符><字母> | <标识符><数学> | <字母>

<无符号数>→<无符号数><数字> | <数字>

<关系符>→= | < | <= | > | >= | <>

<字母>→A | B | C | ··· | X | Y | Z

<数字>→0 | 1 | 2 | ··· | 8 | 9

<空>→

要求和提示:

(1)单词的分类。

可将所有标识符归为一类;将常数归为另一类;保留字和分隔符则采取一词 一类。

(2)符号表的建立。

可事先建立一保留字表,以备在识别保留字时进行查询。变量名表及常数表 则在词法分析过程中建立。

(3)单词串的输出形式。

所输出的每一单词,均按形如(CLASS,VALUE)的二元式编码。对于变量标 识符和常数,CLASS字段为相应的类别码,VALUE字段则是该标识符、常数 在其符号表中登记项的序号(要求在变量名表登记项中存放该标识符的字符 串,其最大长度为四个字符;常数表登记项中则存放该整数的二进制形式)。 对于保留字和分隔号,由于采用一词一类的编码方式,所以仅需在二元式的 CLASS字段上放置相应的单词的类别码,VALUE字段则为“空”。不过,为便 于查看由词法分析程序所输出的单词串,也可以在CLASS字段上直接放置单 词符号串本身。

  • 单词分类表

以下为单词分类表(单词符号,种别编码):

单词符号

种别编码

单词符号

种别编码

auto

1

void

30

break

2

volatile

31

case

3

while

32

char

4

标识符

33

const

5

常型整量

34

continue

6

+

35

default

7

36

do

8

*

37

double

9

/

38

else

10

<

39

enum

11

<=

40

extern

12

>

41

float

13

>=

42

for

14

=

43

goto

15

==

44

if

16

<>

45

int

17

;

46

long

18

(

47

register

19

)

48

return

20

^

49

short

21

,

50

signed

22

#

51

sizeof

23

%

52

static

24

[

53

struct

25

]

54

switch

26

{

55

typedef

27

}

56

union

28

.

57

unsigned

29

//

58

  • 单词状态图
  • 算法描述

1.首先,我将单词类别总分为六大类:

1:标识符

2:数字

3:算数运算符 + – * \

4:关系运算符 <、<=、>、>=、<>、=、==

5:保留字(32)

auto break case char const continue

default do double else enum extern

float for goto if int long

register return short signed sizeof static

struct switch typedef union unsigned void

volatile while

6:界符 ;、(、)、^、,、#、%、[、]、{、}、.、\\

2.每种单词类别的识别及判断方法如下:

首先从文件中读一个字符,赋值给ch,

如果ch为空格,则文件扫描列序号加一;

如果ch为回车,则文件扫描行序号加一;

其它情况如下:

(1)如果ch为字母或下划线,继续扫描,直到ch不是数字、字母或下划 线,则开始判断单词类型:

查找关键字表,若找到匹配项,则为关键字;

否则为标识符,查找标识符表,若没有找到匹配项,则添加到标识符表中。(动态生成标识符表)

如果ch为数字,继续扫描,直到ch不是数字,则开始判断单词类型: 若数字在合法范围内,则为数字,查找标识符表,若没有找到 匹配项,则添加到数字表中;(动态生成数字表)

否则为非法单词。

(2)如果ch是加减乘,一定是算数运算符。

(3)如果ch为;、(、)、^、,、#、%、[、]、{、}、.,则一定是界符。

(4)如果ch为<,则继续扫描下一个:

若下一个为=,则为<=;

若下一个为>,则为<>;

否则,为<。

(5)如果ch为>,则继续扫描下一个:

若下一个为=,则为>=;

否则,为>。

(6)如果ch为/,则继续扫描下一个:

若下一个为/,则为注释,这一行剩下的全被注释了;

否则,则为/。

3.出错处理:

我使用了两个全局变量:line,col,分别用于定位文件中扫描的位置信息,当发现当前字符为非法字符时,输出报错信息,并输出非法字符在文件中的所在位置信息。

4.输出显示:

将所输出的每一单词,均按形如(CLASS,VALUE)的二元式编码。对于变量标识符和常数,CLASS字段为相应的类别码,VALUE字段则是该标识符、常数在其符号表中登记项的序号。对于保留字和分隔号,由于采用一词一类的编码方式,为便于查看由词法分析程序所输出的单词串,所以在CLASS字段上直接放置单词符号串本身,VALUE字段则为“空”。使用分支结构,根据判断结果,从而进行相应输出显示。

  • 程序结构

1.变量常量定义:

对程序所需常量以及全局变量进行定义,其中包含:

(1)全局变量:

int seekresult:fseek的时候用来接着的;

string word=””:字符串,当前词;

char ch:每次读进来的一个字符;

int num=0:每个单词中当前字符的位置;

int line=1:行数;

int col=1:列数;

bool flag:文件是否结束扫描;

int type;:单词的类型;

char IDentifierTable[1000][40]:标识符表;

char DigitBTable[1000][40]常数表等。

(2)常量:

static char ReserveWord[32][20]:保留字表;

static char SuanshuOperator[4][4]:算术运算符表;

static char GuanxiOperator[7][4]:逻辑运算符表;

static char Jiefu[36][4]:界符表。

2.主要函数:

(1)bool Isletter(char x)函数:判断字符x是否为字母;

(2)bool IsDigit(char x)函数:判断字符x是否为数字;

(3)bool IsJiefu(char x)函数:判断字符x是否为界符;

(4)bool IsSuanshuyunsuanfu(char x) 函数:判断字符x是否为算数运算符;

(5)bool IsGuanxiyunsuanfu(char x)函数:判断字符x是否为关系运算符;

(6)int Scanner(FILE *fp)函数:其主要功能为从文件里读一个单词,调用基础函数进行单词类别,。

(7)int main()函数:程序入口,进行文件扫描,并调用Scanner(FILE *fp)函数对单词进行判断,输出分析结果。

  • 运行结果

1.待分析文件code.txt:

2.运行结果:

3.文件目录:

4.常数表:

5.标识符表:

  • 调试情况

在此次实验中,遇到的问题还是比较多的,主要分为以下几种:

1.读文件和写文件操作:

由于待分析内容存储在文本文件中,所以文件的读取是必不可少的操作;而单词分析时需要动态生成标识符表和常数表,故需要追写文件。一开始由于语言功底不太扎实,实现的不太顺利,但是在上网查找了解决方案以后,问题就迎刃而解了。

2.各种单词类别的识别和判断以及出错处理:

这是词法分析器的核心也是难点,这部分必须逻辑十分清晰才可以实现,一开始虽然听懂了课堂上的内容,但是理解的还是不够深刻,感觉自己已经将单词类别进行了合理的划分,但是具体实现细节上还是遇到了不少的困难。比如,在一些相似单词的识别上面困惑了一段时间,想到了老师上课所说的“超前搜索”算法,所以我进行了实现,但是发现位置定位是一个需要特别关注的问题,我的解决方案就是:添加两个全局位置变量以及一些局部位置变量,将文件中现在正在扫描的位置以及这个单词第一个字符的位置信息记录下来,然后捋清他们之间的关系以及使用目的,则问题也就解决了,并且也使得报错信息可以包含非法字符在文件中的位置所在。

3.标识符表和常数表的动态生成:

关于这个问题的解决,我将它放在了识别的过程当中,就可以做到动态生成,并且添加了文件追写,则可以在文件中查看生成的表信息了。

4.输出显示:

这个问题一开始实现的有些困难,当我发现它的重心在于认清每个单词的分类情况,并通过识别结果就可以很好的实现了。

  • 测试文件 code.txt
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int main(void) {
  int min=2, mid=3, max=1, t;
  if (min > mid) {
    t = min;
    min = mid;
    mid = t;
  }
  if (min > max) {
    t = min;
    min = max;
    max = t;
  }
  if (mid > max) {
    t = mid;
    mid = max;
    max = t;
  }
}
  • 源代码
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<iostream>
#include<fstream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
using namespace std;
/*
1:标识符
2:数字 
3:算数运算符 + - * 
4:关系运算符 <=、  >=、  <>、  == =、 <、>
5:保留字(32)
auto       break    case     char        const      continue
default    do       double   else        enum       extern
float      for      goto     if          int        long
register   return   short    signed      sizeof     static
struct     switch   typedef  union       unsigned   void
volatile    while
6:界符 
*/
int seekresult;		//fseek的时候用来接着的 
string word="";		//字符串,当前词 
char ch;			//每次读进来的一个字符
int num=0;			//每个单词中当前字符的位置
int line=1;			//行数
int col=1;			//列数
bool flag;			//文件是否结束扫描 
int type;			//单词的类型
//保留字表
static char ReserveWord[32][20] = {
"auto", "break", "case", "char", "const", "continue",
"default", "do", "double", "else", "enum", "extern",
"float", "for", "goto", "if", "int", "long",
"register", "return", "short", "signed", "sizeof", "static",
"struct", "switch", "typedef", "union", "unsigned", "void",
"volatile", "while"
};
//算术运算符表
static char SuanshuOperator[4][4] = {
"+", "-", "*", "/"
};
//逻辑运算符表 
static char GuanxiOperator[7][4] = {
"<", "<=", ">", ">=", "=", "==","<>"
};
//界符表(12)
static char Jiefu[36][4] = {
";", "(", ")", "^", ",", "#","%", "[", "]", "{", "}","."
};
//标识符表
//string IDentifierTable[1000] = { "" };
char IDentifierTable[1000][40] = {};
//常数表 
//int DigitBTable[1000][50] = {};
char DigitBTable[1000][40] = {};
int Inum=0;
int Dnum=0;
//判断是否是:字母
bool Isletter(char x)
{
if((x>='a'&&x<='z')||(x>='A'&&x<='Z'))
return true;
else return false;
}
//判断是否是:数字 
bool IsDigit(char x)
{
if(x>='0'&&x<='9')
return true;
else
return false;
}
//判断是否是:界符 
bool IsJiefu(char x) 
{
int i=0;
int temp=0;
for(i=0;i<14;i++)
{
if( x == Jiefu[i][0] )
{
temp=1;
break;
} 
}
if( temp == 1 )
return true;
else
return false;
}
//判断是否是 算数运算符:加减乘
bool IsSuanshuyunsuanfu(char x)
{
if(x=='+'||x=='-'||x=='*')
return true;
else return false;
}
//判断是否是 关系运算符:等于(赋值),大于小于(大于等于,小于等于,大于小于) 
bool IsGuanxiyunsuanfu(char x)
{
if(x=='='||x=='<'||x=='>')
return true;
else
return false;
} 
//从文件里读一个单词 
int Scanner(FILE *fp)
{
//先读一个字符,赋值给ch 
ch=fgetc(fp);
if(feof(fp)){
flag=0;
return 0;
}
else if(ch==' ')
{
col++;
return 0;
}
else if(ch=='\n')
{
line++;
col=1;
return 0;
}
//如果是字母开头或 '_' 看关键字还是标识符 
else if( Isletter(ch) || ch=='_' )
{
word+=ch;
col++;
while( (ch=fgetc(fp)) && ( Isletter(ch) || IsDigit(ch) || ch=='_'))
{
word+=ch;
col++;
}
//文件读完,返回true
if(feof(fp)){
flag=0;
return 1;
}
//检验是否是保留字 
for(int i=1;i<=32;i++){
if( word == ReserveWord[i] ){
//SEEK_CUR当前位置,fseek函数作用:文件位置指针从当前位置位移一个位置 
seekresult=fseek(fp,-1,SEEK_CUR);
//5+i-1:保留字 
return 5+i-1;
}
}
for(int Ii=0;Ii<Inum;Ii++)
{
if(Inum!=0 && strcmp(IDentifierTable[Ii],word.c_str())==0)
{
seekresult=fseek(fp,-1,SEEK_CUR);	
//1:标识符 
//return 1;
return 1000+Ii+1;
}
}
strcpy(IDentifierTable[Inum],word.c_str());
Inum=Inum+1;
//写追加 
ofstream Arithmetic_operator;
Arithmetic_operator.open("IDentifierTable.txt",ios::app);
Arithmetic_operator<<word<<" "<<endl;
Arithmetic_operator.close();
seekresult=fseek(fp,-1,SEEK_CUR);	
//1:标识符 
//return 1;
return 1000+Inum;
}
//开始是加减乘,一定是算数运算符3 
else if(IsSuanshuyunsuanfu(ch))
{
word+=ch;
col++;
//3:算数运算符 
return 3;
}
//开始是数字就一定是数字2 
else if(IsDigit(ch))
{
word+=ch;
col++;
while((ch=fgetc(fp)) && IsDigit(ch))
{
word+=ch;
col++;
}
int Di=0;
for(Di=0;Di<Inum;Di++)
{
if(Dnum!=0 && strcmp(DigitBTable[Di],word.c_str())==0)
{
seekresult=fseek(fp,-1,SEEK_CUR);	
//2:数字 
//return 2;
return 2000+Di+1;
}
}
strcpy(DigitBTable[Dnum],word.c_str());
Dnum=Dnum+1;
//写追加 
ofstream Arithmetic_operator;
Arithmetic_operator.open("DigitBTabl.txt",ios::app);
Arithmetic_operator<<word<<" "<<endl;
Arithmetic_operator.close();
//        if(feof(fp)){
//                flag=0;
//				return 2;
//        }
seekresult=fseek(fp,-1,SEEK_CUR);
//2:数字 
return 2000+Dnum;
}
//检验界符6 
else if(IsJiefu(ch))
{
int Ji;
for(Ji=0;Ji<12;Ji++)
{
if( ch == Jiefu[Ji][0] )
{
break;
} 
}
word+=ch;col++;
//6-1+32+i:界符 
return (6-1+32+Ji);
}
//检验关系运算符4 :<=、>=、<>、==、 < 、>
else if( IsGuanxiyunsuanfu(ch) )
{
col++;
word+=ch;
//检验  <> <=
if(ch=='<')   
{
ch=fgetc(fp);
if(ch=='>' || ch=='=')
{
word+=ch;
col++; 
return 4;
}
}
//检验  >= ==
else{
ch=fgetc(fp);
if(ch=='=')
{
word+=ch;
col++;
return 4;
}
}
if(feof(fp)){
flag=0;
}
seekresult=fseek(fp,-1,SEEK_CUR);
//3:算数运算符 
return 3;
}
//首字符是 / 有可能是除号 也有可能是注释
else if(ch=='/')
{
col++;word+=ch;
ch=fgetc(fp);
//这种情况是除号
if(ch!='*' && ch !='/')
{
seekresult=fseek(fp,-1,SEEK_CUR);
//3:算数运算符 
return 3;
}
//注释符//:这一行剩下的全被注释了
if(ch=='/')
{
word.clear();
while((ch=fgetc(fp)) && ch!='\n' && !feof(fp) )
{}
if(feof(fp)){
flag=0;
return 0;
}
else{
seekresult=fseek(fp,-1,SEEK_CUR);
}
line++;col=1;
return 0;
}
if(ch=='*')
{
bool flag5=1;
while(flag5)
{
word.clear();
ch=fgetc(fp);
col++;
if(ch=='\n')
{
line++;
col=1;
}
if(ch!='*')
continue;
else 
{
ch=fgetc(fp);
col++;if(ch=='\n'){line++;col=1;}
if(ch=='/'){
flag5=0;
}
else continue;
}
if(feof(fp))
{
flag=0;
return 0;
}
}
}
}
else {
word+=ch;
col++;
return -1;
}
}
int main()
{
FILE *fp;
cout<<"open "<<"code.txt"<<endl;
system("pause");
flag=1;
//打开源代码文件 
//未打开 
if((fp=fopen("code.txt","r"))==NULL)
{
cout<<"Sorry,can't open this file."<<endl;
flag=0;
}
//已打开 
while(flag==1)
{
//反复调用扫描函数提取单词
type=Scanner(fp);	
//1:标识符
if(type>1000&&type<2000)
{
//cout<<"type:1 identifier      "<<"line "<<line<<" col "<<col-word.length()<<"  "<<word<<endl;
cout<<"("<<word<<","<<type-1000<<")"<<endl; 
if(word.length()>20)
cout<<"ERROR Identifier length cannot exceed 20 characters"<<endl;
word.clear();
}
//2:数字   
else if(type>2000)
{
//cout<<"type:2 positive number "<<"line "<<line<<" col "<<col-word.length()<<"  "<<word<<endl;
cout<<"("<<word<<","<<(type-2000)<<")"<<endl;
if(word[0]=='0')
cout<<"ERROR: The first digit cannot be 0!"<<endl;
word.clear();
}
//3:算数运算符 + - * / 
else if(type==3)
{
//cout<<"type:3 unary_operator  "<<"line "<<line<<" col "<<col-1<<"  "<<word<<endl;
cout<<"("<<word<<","<<"3"<<")"<<endl;
word.clear();
}
//4:关系运算符 <、<=、>、>=、= 、<> 
else if(type==4)
{
//cout<<"type:4 double_operator "<<"line "<<line<<" col "<<col-2<<"  "<<word<<endl;
cout<<"("<<word<<","<<"4"<<")"<<endl;
word.clear();
}
//6-1+32 - 6-1+32+11:界符
else if(type>=37)
{
//cout<<"type:5 Separator       "<<"line "<<line<<" col "<<col-1<<"  "<<word<<endl;
cout<<"("<<word<<","<<"_"<<")"<<endl;
//cout<<"("<<type<<","<<"_"<<")"<<endl;  
word.clear();
}
//5 - 5-1+32:保留字 
else if( type>=5 && type<=36)
{
//cout<<"type:6 reserved word   "<<"line "<<line<<" col "<<col-word.length()<<"  "<<word<<endl;
cout<<"("<<word<<","<<"_"<<")"<<endl;
//cout<<"("<<type<<","<<"_"<<")"<<endl;  
word.clear();
}
//非法字符
else if(type==-1)
{
cout<<"Illegal character   "<<"line "<<line<<" col "<<col-1<<"  "<<word<<endl;
word.clear();
}
}
int a=fclose(fp);
cout<<"Do you want to close?(Y or N)"<<endl;
char end;
while(cin>>end && end!='Y'){
cout<<"Do you want to close?(Y or N)"<<endl;
}
return 0;
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/206288.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年10月24日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【编译原理】词法分析:C/C++实现
编译原理是计算机科学领域的一个重要分支,它研究如何将高级编程语言的源代码转化成计算机能够执行的机器代码或中间代码的过程。编译原理涵盖了编译器的设计和实现,其中编译器是一种将源代码翻译成目标代码的软件工具。编译器的主要任务包括语法分析、词法分析、语义分析、优化和代码生成等环节。
SarPro
2024/02/20
1.7K0
【编译原理】词法分析:C/C++实现
简易C语言词法分析程序
浪漫主义狗
2024/03/22
1840
【编译原理】S语言词法分析器设计-附雪景图
前几天下雪了,不知道为啥一到下雪或是下雨就有些淡淡的忧郁,但是雪还是很漂亮的,分享一下我拍的雪景图和剪的视频吧(其实就是配了段音乐),希望我们每个在努力路上的人都会有一路美好的风景吧,祝我们终将成功。
NorthS
2023/03/21
4600
【编译原理】S语言词法分析器设计-附雪景图
编译原理课程设计词法分析
主要实现对文本中的程序进行词法分析,把程序中的单词分为五大类(基本保留字[1]、标识符[2]、常数[3]、运算符[4]、分隔符[5])并与相应的区域数字来对应输出.
程序员小藕
2020/07/28
1.2K0
编译原理实验一词法分析器_编译原理词法错误举例
实验目的:理解词法分析在编译程序中的作用; 加深对有穷自动机模型的理解; 掌握词法分析程序的实现方法和技术。
全栈程序员站长
2022/11/10
7480
编译原理实验一词法分析器_编译原理词法错误举例
Java编写的C语言词法分析器
    这是java编写的C语言词法分析器,我也是参考很多代码,然后将核心代码整理起来,准备放在QQ空间和博客上,目的是互相学习借鉴,希望可以得到高手改进。这个词法分析器实现的功能有打开文件、保存文件、打开帮助文档、文本域内容的剪切和复制和黏贴、进行词法分析 程序的项目结构如图,Word类和Unidentifiable类是两个JavaBean类,存放的参数有两个row(整型)、word(String),row用于获取行数,word用于获取标识符,LexerFrame是词法分析器的界面类,Analyze封装了进行词法分析的核心代码 ,doc文件夹放一个帮助文档,当用户点击帮助按钮时可以弹出来以帮助用户使用。 Github项目链接:https://github.com/u014427391/lexer1.1.0,欢迎star //核心程序:
SmileNicky
2019/01/17
1.2K0
Java入门基础知识点总结(详细篇)
定义:被Java语言赋予了特殊含义,用做专门用途的字符串(单词) 特点:关键字中所有字母都为小写
全栈程序员站长
2022/09/08
4.3K0
Java入门基础知识点总结(详细篇)
A - 小C语言--词法分析程序
小C语言文法  1. <程序>→<main关键字>(){<声明序列><语句序列>} 2. <声明序列>→<声明序列><声明语句>|<声明语句>|<空> 3. <声明语句>→<标识符表>; 4. <标识符表>→<标识符>,<标识符表>|<标识符> 5. <语句序列>→<语句序列><语句>|<语句> 6. <语句>→< if语句>|< while语句>|< for语句>|<复合语句>|<赋值语句> 7. < if语句>→< if关键字>(<表达式>)<复合语句>|(<表达式>)<复合语句>< else关键字><复合语句> 8. < while语句>→< while关键字>(<表达式>)<复合语句> 9. < for语句>→< for关键字>(<表达式>;<表达式>;<表达式>)<复合语句> 10. <复合语句>→{<语句序列>} 11. <赋值语句>→<表达式>; 12. <表达式>→<标识符>=<算数表达式>|<布尔表达式> 13. <布尔表达式>→<算数表达式> |<算数表达式><关系运算符><算数表达式> 14. <关系运算符>→>|<|>=|<=|==|!= 15. <算数表达式>→<算数表达式>+<项>|<算数表达式>-<项>|<项> 16. <项>→<项>*<因子>|<项>/<因子>|<因子> 17. <因子>→<标识符>|<无符号整数>|(<算数表达式>) 18. <标识符>→<字母>|<标识符><字母>|<标识符><数字> 19. <无符号整数>→<数字>|<无符号整数><数字> 20. <字母>→a|b|…|z|A|B|…|Z 21. <数字>→0|1|2|3|4|5|6|7|8|9
Lokinli
2023/03/09
1.5K0
词法分析器(Lexer)的实现
写下Compiler系列的主要目的,是为了记录一下本人在学习编译原理以及做出一个简单的Compiler的历程,为后续向二进制安全的更深领域的学习打下基础。
h1J4cker
2022/12/01
1.9K0
C++基础快速入门
​ Visual Studio是我们用来编写C++程序的主要工具,我们先将它打开
HelloWorldZ
2024/03/20
2120
C++基础快速入门
词法分析程序
程序分为4个关键方法,用户输入方法,读、写文件方法以及词法分析方法。其中词法分析方法是程序的核心。 词法分析程序主要分为两个部分,第一是取词,第二是分析。 取词阶段: 依次取字符串的每一个字符,遇到空字符时停下,将取到的字符合并成一个字符串,送去进行分析阶段。 分析阶段:程序先构建有关键字数组、分隔符数组和运算符数组,通过将取词阶段送来的字符串与各数组中元素进行比较,将字符串分类到相应的类别数组中保存。 词法分析伪代码如下: While (源码字符串没有取完){ Getchar(获取一个非空字符);
SuperHeroes
2018/05/30
1.1K0
如何编写一个 Python 词法分析器
Python 词法分析器是一种可以将 Python 代码分解成一组记号的程序。这些记号是 Python 语法的基本组成单位,包括标识符、关键字、运算符、分隔符等。词法分析器在 Python 解释器中扮演着重要的角色,它负责将源代码转换为计算机可以理解的形式。
用户11021319
2024/03/22
2030
如何编写一个 Python 词法分析器
数字证书结构描述+解析的C程序设计和实现
版本(version)为整数格式。到目前为止,证书格式的版本只有v1、v2、v3,分别用整数0、1、2表示。
梦飞
2022/06/23
8060
数字证书结构描述+解析的C程序设计和实现
从词法分析角度看 Go 代码的组成
之前的 Go 笔记系列,已经完成到了开发环境搭建,原本接下来的计划就是到语法部分了,但后来一直没有前进。主要是因为当时的工作比较忙,分散了精力,于是就暂时放下了。
波罗学
2019/11/06
5090
Java的基本语法。
在java语言中,用来标志类名、对象名、变量名、方法名、类型名、数组名、包名的有效字符序列,称为“标识符”;
7537367
2020/07/28
5480
编译原理学习(到LL1文法部分)
机器语言:计算机只认识由0和1构成的机器语言,每台机器自己独特的指令系统即机器语言。 机器语言->汇编语言->高级语言 编译程序最初的定义是把一种高级语言设计的源程序(面向人的)翻译成另一种等价的低级程序设计语言(面向硬件的)即机器语言或汇编语言。
且陶陶
2023/04/12
8010
编译原理学习(到LL1文法部分)
SDUT编译原理上机测试
这题需要注意的是,对于句子:E \rightarrow TG 和 T \rightarrow FS 需要先判断一下 SELECT 集再进行递归,如果输入字符不属于 SELECT 集则直接输出 ERROR。
Here_SDUT
2022/09/19
9880
javascript入门到进阶 - javascript词法文法
这部分描述了JavaScript的词法。ECMAScript源码文本会被从左到右扫描,并被转换为一系列的输入元素,包括tokens、控制符、行终止符、注释和空白符。ECMAScript定义了一些关键字、字面量以及行尾分号补全的规则。
公众号---人生代码
2020/07/14
7770
从 Python 到 C++:第一步——基础语法结构与数据类型对比学习
年也过完了,心也该静下来了,上年立的flag也变成今年的了,再喊一遍口号,今年要更努力,把c++学会并将c++学习笔记系列更新完毕。敬请期待~
不止于python
2025/03/17
1040
从 Python 到 C++:第一步——基础语法结构与数据类型对比学习
PL/0语言编译程序分析
  PL/0语言是Pascal语言的一个子集,我们这里分析的PL/0的编译程序包括了对PL/0语言源程序进行分析处理、编译生成类PCODE代码,并在虚拟机上解释运行生成的类PCODE代码的功能。   PL/0语言编译程序采用以语法分析为核心、一遍扫描的编译方法。词法分析和代码生成作为独立的子程序供语法分析程序调用。语法分析的同时,提供了出错报告和出错恢复的功能。在源程序没有错误编译通过的情况下,调用类PCODE解释程序解释执行生成的类PCODE代码。   词法分析子程序分析:   词法分析子程序名为get
逍遥剑客
2018/05/21
1.8K0
相关推荐
【编译原理】词法分析:C/C++实现
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验