C语言:输入为 PL/0 源程序, 输出为单词符号的序列;对于标识符和无符号整数,显示单词种别和单词自身的值两项内容;对于其他单词符号,仅显示其单词种别
时间: 2024-05-10 09:19:03 浏览: 97
C语言有符号数和无符号数运算
5星 · 资源好评率100%
以下是一个简单的C语言程序,可以实现将PL/0源程序转换为单词符号序列,并对标识符和无符号整数进行分类和显示:
```c
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAXLEN 100 // 最大单词长度
// 单词种别
typedef enum {
nul, ident, number, plus, minus, times, slash, oddsym,
eql, neq, lss, leq, gtr, geq, lparen, rparen, comma,
semicolon, period, becomes, beginsym, endsym, ifsym,
thensym, whilesym, dosym, callsym, constsym, varsym,
procsym, writesym, readsym
} symbol;
// 单词符号结构体
typedef struct {
symbol kind; // 单词种别
char name[MAXLEN+1]; // 单词自身的值
} token;
// 全局变量
char ch; // 当前读入的字符
int num; // 当前读入的数字
char id[MAXLEN+1]; // 当前读入的标识符
int pos = 0; // 当前读取到的单词符号序列的位置
token tokens[MAXLEN+1]; // 单词符号序列
void getch() {
ch = getchar();
}
void getnum() {
num = 0;
while (isdigit(ch)) {
num = num * 10 + ch - '0';
getch();
}
}
void getid() {
int i = 0;
while (isalpha(ch) || isdigit(ch)) {
if (i < MAXLEN) {
id[i++] = ch;
}
getch();
}
id[i] = '\0';
}
void error() {
printf("Invalid character: %c\n", ch);
}
symbol getsym() {
while (isspace(ch)) {
getch();
}
if (isdigit(ch)) {
getnum();
return number;
} else if (isalpha(ch)) {
getid();
if (strcmp(id, "begin") == 0) {
return beginsym;
} else if (strcmp(id, "end") == 0) {
return endsym;
} else if (strcmp(id, "if") == 0) {
return ifsym;
} else if (strcmp(id, "then") == 0) {
return thensym;
} else if (strcmp(id, "while") == 0) {
return whilesym;
} else if (strcmp(id, "do") == 0) {
return dosym;
} else if (strcmp(id, "call") == 0) {
return callsym;
} else if (strcmp(id, "const") == 0) {
return constsym;
} else if (strcmp(id, "var") == 0) {
return varsym;
} else if (strcmp(id, "procedure") == 0) {
return procsym;
} else if (strcmp(id, "write") == 0) {
return writesym;
} else if (strcmp(id, "read") == 0) {
return readsym;
} else {
return ident;
}
} else {
switch (ch) {
case '+': getch(); return plus;
case '-': getch(); return minus;
case '*': getch(); return times;
case '/': getch(); return slash;
case '=': getch(); return eql;
case '<': getch();
if (ch == '=') {
getch();
return leq;
} else if (ch == '>') {
getch();
return neq;
} else {
return lss;
}
case '>': getch();
if (ch == '=') {
getch();
return geq;
} else {
return gtr;
}
case '(': getch(); return lparen;
case ')': getch(); return rparen;
case ',': getch(); return comma;
case ';': getch(); return semicolon;
case '.': getch(); return period;
case ':': getch();
if (ch == '=') {
getch();
return becomes;
} else {
error();
return nul;
}
default: error(); getch(); return nul;
}
}
}
int main() {
printf("Enter PL/0 source code:\n");
// 读入PL/0源程序
int i = 0;
do {
ch = getchar();
if (i < MAXLEN && ch != '\n') {
id[i++] = ch;
}
} while (ch != '\n');
// 词法分析
do {
symbol sym = getsym();
if (sym == ident || sym == number) {
tokens[pos].kind = sym;
strncpy(tokens[pos].name, id, MAXLEN);
tokens[pos].name[MAXLEN] = '\0';
printf("(%d, %s)\n", sym, id);
} else {
tokens[pos].kind = sym;
printf("%d\n", sym);
}
pos++;
} while (tokens[pos-1].kind != period);
return 0;
}
```
程序读入PL/0源程序后,依次进行词法分析,将单词符号序列存储在`tokens`数组中。当读取到标识符或无符号整数时,不仅显示单词种别,还显示单词自身的值。其他单词符号只显示其单词种别。
阅读全文