编译原理_PL/0_词法分析

词法分析器

一、实验要求:

PL0语言设计一个词法分析器,能够识别PL0语言编写的程序中的单词的合法性。

二、实验分析:

PL0语言是与pascal类似的语言,但是比pascal语言的词法、语法更加严格苛刻。

PL0语言中,只有五种类型的单词:关键字、用户自定义标识符、数字、特殊符号以及非法标识符。

根据题目给出的PL0的文法,关键字只有如下几个:

Const——用来声明常量;

Var——用来声明变量;

Procedure——用来声明过程;

Begin——声明过程的开始;

End——声明过程的结束;

Ood——单目运算符,声明为关键字;

If——条件语句;

Then——条件语句;

Call——声明调用函数;

While——循环语句;

Read——读文件语句;

Write——写文件语句;

对于用户自定义标识符应该满足:以字母开头,其后是字母和数字的组合,即:字母(字母|数字)*

数字则是数字字符(0——9)组成的数字串;

特殊符号有如下几个:
+-*/=<>,<,>=,<=,:=

把关键字、算符和界符称为语言固有的单词,标识符、常量称为用户自定义的单词。

为此设置三个全程量:SYM,ID,NUM

SYM:存放每个单词的类别,为内部编码的表示形式;

ID:存放用户所定义的标识符的值,即标识符字符串的机内表示;

NUM:存放用户定义的数。

三、设计方案:
   1)对于关键字,应该为每个关键字分配一个类别,该类别在机器内部为内部编码的表示形式;

    采用枚举型,将所有的关键字放在一个表中,这样每一个关键字都分配到了一个内部编码;

   2)对于用户自定义的标识符,应该给他们一个统一的类别——SYM_IDENTIFIER

   3)对于所有的特殊符号(例如+-等),与关键字的处理方法一样给每一个符号分配一个类别。

   4)上述所有的类别均放在一个枚举类型表中。

   5)对于关键字,还应该有一个字符串类型的表,用来存储每一个关键字的名称。当词法分析器读入一个单词的时候,首先判断是不是关键字时,立马转入到表中,和表中的关键字进行匹配,如果匹配成功,则读入的标识符时关键字,否则进行进一步的判断;

四、程序设计:

   PL/0语言建立一个词法分析程序GETSYM(函数)

   GETSYM要完成的任务:

1、滤掉单词间的空格;

2、识别关键字,用查关键字表的方法识别。当单词是关键字时,将对应的类别放在SYM中;

3、识别标识符,标识符的类别为SYM_IDENTIFIERSYM_IDENTIFIER放在SYM中,标识符本身的值放在ID中。关键字或者标识符的最大长度是10

4、拼数,将数的类别NUMBER放在SYM中,数本身的值放在NUM中;

5、拼由两个字符组成的运算符,如:>=,<=等等,识别后将类别放在SYM中;

6、错误处理,如果读入不能识别的单词、或者非法的字符、或者长度超过10的字符,就会报错。定义一个全局变量line记录当前读到程序的行数,报错时指示错误的行数;

7、打印源程序,边都入字符表打印;

8、为GETSYM设计一个GETCH

阅读终点,创作起航,您可以撰写心得或摘录文章要点写篇博文。去创作
  • 18
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
好的,我可以为您提供一些关于pl/0语言词法分析器的C++实现的相关信息。 首先,pl/0是一种简单的过程化语言,常用于编译原理的教学中。它的语法比较简单,只有少数的语法元素,如变量声明、赋值语句、条件语句、循环语句等。 其次,词法分析器是编译器的一个组成部分,它的作用是将源代码中的字符序列转换为单词序列,也就是词法单元。在pl/0语言中,词法单元包括关键字、标识符、常数、运算符等。 下面是一个简单的pl/0语言词法分析器的C++实现,供您参考: ```c++ #include <iostream> #include <string> #include <cctype> using namespace std; enum TokenType { KEYWORD, IDENTIFIER, NUMBER, OPERATOR, DELIMITER, ERROR }; struct Token { TokenType type; string value; }; string keywords[] = { "const", "var", "procedure", "begin", "end", "if", "then", "else", "while", "do", "call", "read", "write", "odd" }; string operators[] = { "+", "-", "*", "/", "=", "<>", "<", "<=", ">", ">=", ":=" }; string delimiters[] = { ",", ";", ".", "(", ")" }; bool isKeyword(string str) { for (int i = 0; i < 14; i++) { if (keywords[i] == str) { return true; } } return false; } bool isOperator(string str) { for (int i = 0; i < 11; i++) { if (operators[i] == str) { return true; } } return false; } bool isDelimiter(string str) { for (int i = 0; i < 5; i++) { if (delimiters[i] == str) { return true; } } return false; } Token lex(string input) { Token token; token.value = input; if (isKeyword(input)) { token.type = KEYWORD; } else if (isdigit(input[0])) { token.type = NUMBER; for (int i = 1; i < input.length(); i++) { if (!isdigit(input[i])) { token.type = ERROR; break; } } } else if (isOperator(input)) { token.type = OPERATOR; } else if (isDelimiter(input)) { token.type = DELIMITER; } else { token.type = IDENTIFIER; } return token; } int main() { string input; cout << "Enter a pl/0 language token: "; cin >> input; Token token = lex(input); cout << "Token value: " << token.value << endl; switch (token.type) { case KEYWORD: cout << "Token type: keyword" << endl; break; case IDENTIFIER: cout << "Token type: identifier" << endl; break; case NUMBER: cout << "Token type: number" << endl; break; case OPERATOR: cout << "Token type: operator" << endl; break; case DELIMITER: cout << "Token type: delimiter" << endl; break; case ERROR: cout << "Token type: error" << endl; break; } return 0; } ``` 该程序首先定义了一个枚举类型`TokenType`,用于标识词法单元的类型。然后定义了一个`Token`结构体,包含了词法单元的类型和值。 接着定义了三个字符串数组,分别存储关键字、运算符和分隔符。通过`isKeyword`、`isOperator`和`isDelimiter`函数判断输入字符串是否为关键字、运算符或分隔符。 最后定义了`lex`函数,用于将输入的字符串转换为`Token`结构体。该函数首先判断输入字符串的类型,然后返回一个`Token`结构体。 在`main`函数中,通过调用`lex`函数将输入字符串转换为一个`Token`结构体,并根据其类型输出相应的信息。 以上就是一个简单的pl/0语言词法分析器的C++实现,希望能对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安全

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值