📄 pl0scan.c
字号:
/*******************************************************************
Program : Recursive Descent Compiler for PL/0
Module : PL0SCAN - Scanner: lexical analysis
File : pl0scan.c
Compiler: Borland C 3.1 - 4.5, GNU C 2.7.1
Author : H. Weber
Revision: Aug. 1998
********************************************************************/
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include "pl0const.h"
#include "pl0glob.h"
FILE *source, *listing, *token;
int eofflag = 0;
int sym, num;
int lineno = 1;
char id[cmax];
char str[strmax];
char ch = ' '; /* to begin */
void error()
{
fprintf(stderr, "Premature end of file\n");
exit(1);
}
void initsym()
/* initialization of the ssym array */
{
int i;
for (i=0; i<256; i++)
ssym[i] = 0;
ssym['+'] = plus;
ssym['-'] = minus;
ssym['*'] = times;
ssym['/'] = slash;
ssym['('] = lparen;
ssym[')'] = rparen;
ssym['.'] = period;
ssym['#'] = neq;
ssym['='] = eql;
ssym[','] = comma;
ssym['<'] = lss;
ssym['>'] = gtr;
ssym[';'] = semicolon;
ssym[':'] = colon;
return;
}
int readchar()
/* read a character from source input and
write it on listing file */
{
char c;
c = fgetc(source);
if (c == EOF) eofflag = 1;
fputc(c, listing);
if (c == '\n') {
fprintf(listing, "%3d ", ++lineno);
fprintf(token, "%2d\n", lf);
}
return c;
}
void findresw()
/* find reserved words */
{
int i, j, k;
i = 1;
j = norw; /* check for reserved word */
do {
k = (i+j)/2;
if (strcmp(id, word[k]) <= 0) j = k-1;
if (strcmp(id, word[k]) >= 0) i = k+1;
} while (i <= j);
if (i-1 > j)
sym = wsym[k]; /* symbol is reserved word */
else
sym = ident; /* symbol is an identifier */
}
int getsym()
/*------------------------------------------------------------------
The function getsym provides the next symbol from the source
program. The result is output in the following variables:
sym: contains the type or internal representation of the
next symbol
num: contains the value of a number
id : contains the character string defining an identifier
or reserved word
str: contains a character string belonging to a write-
statement
-------------------------------------------------------------------*/
{
int digit, endstring, k; // i, j,
go:
if (eofflag) return 0;
/* pass over leading blanks, tabs, etc. */
while (isspace(ch)) ch = readchar();
/* next symbol is identifier or reserved word */
if (isalpha(ch) && islower(ch))
{
strcpy(id, "");
k = 0;
do {
if (k < cmax-1)
id[k++] = ch;
ch = readchar();
} while (isalpha(ch) || isdigit(ch));
id[k] = 0;
findresw();
}
/* next symbol is a number */
else if (isdigit(ch))
{
num = 0;
sym = number;
do {
digit = ch - '0';
if ((num < imax/10) ||
((num == imax/10) && (digit <= imax % 10)))
num = num*10 + digit;
else {
num = 0;
fprintf(stderr, "Wrong number in input file\n");
}
ch = readchar();
} while (isdigit(ch));
}
/* next symbol is ':' or ':=' */
else if (ch == ':')
{
ch = readchar();
if (ch == '=') {
sym = becomes;
ch = readchar();
}
else
sym = colon;
}
/* next symbol is '<' or '<=' */
else if (ch == '<') /* next symbol is '<' or '<=' */
{
ch = readchar();
if (ch == '=') {
sym = leq;
ch = readchar();
}
else
sym = lss;
}
/* next symbol is '>' or '>=' */
else if (ch == '>')
{
ch = readchar();
if (ch == '=') {
sym = geq;
ch = readchar();
}
else
sym = gtr;
}
/* next symbol is string */
else if (ch == '\'')
{
num = 0;
ch = readchar();
sym = stringsym;
endstring = 0;
do {
if (ch == '\'') {
ch = readchar();
endstring = (ch != '\'');
}
if (!endstring) {
str[num++] = ch;
ch = readchar();
if (eofflag) error();
}
} while (!endstring);
if (!endstring) num = 0;
str[num++] = 0;
}
/* next symbol is '(' or possibly comment */
else if (ch == '(')
{
ch = readchar();
if (ch != '*')
sym = lparen;
else /* comment */
{
ch = readchar();
do {
while (ch != '*') {
if (eofflag) error();
ch = readchar();
}
ch = readchar();
} while (ch != ')');
ch = readchar();
if (eofflag) error();
goto go;
}
}
else if (ch == EOF)
return 0;
/* special symbol */
else
{
sym = ssym[ch];
if (sym == 0) {
fprintf(stderr,
"Wrong character: '%c' found in source.\n", ch);
ch = readchar();
goto go;
}
else
ch = readchar();
}
return 1;
}
void main(int argc, char *argv[])
/*------------------------------------------------------------------
The main function of the scanner reads the source file and
writes the symbols of the source program on an intermediate
file.
------------------------------------------------------------------*/
{
char sname[20], lname[20], tname[20];
char *p;
printf("PL/0-Compiler: Scanner\n");
/* check arguments */
// if (argc == 1) {
// fprintf(stderr, "Usage: %s source\n", argv[0]);
// exit(1);
// }
/* set up filenames */
// strcpy(sname, argv[1]);
strcpy(sname, "prim.pl0");
p = strchr(sname, '.');
if (p) *p = 0;
strcpy(lname, sname);
strcpy(tname, sname);
strcat(sname, ".pl0");
strcat(lname, ".lst");
strcat(tname, ".tok");
/* open files */
if ((source = fopen(sname, "r")) == NULL) {
fprintf(stderr, "Cannot open source file %s\n", sname);
exit(1);
}
if ((listing = fopen(lname, "w")) == NULL) {
fprintf(stderr, "Cannot open listing file %s\n", lname);
exit(1);
}
if ((token = fopen(tname, "w")) == NULL) {
fprintf(stderr, "Cannot open token file %s\n", tname);
exit(1);
}
fprintf(listing, "Source file: %s\n\n", sname);
fprintf(listing, " 1 ");
/* initialize symbols */
initsym();
/* main loop */
while (getsym()) {
fprintf(token, "%2d ", sym);
if (sym == ident)
fprintf(token, "%s\n", id );
else if (sym == number)
fprintf(token, "%d\n", num);
else if (sym == stringsym)
fprintf(token, "%s\n", str);
else
fprintf(token, "\n");
}
/* close files */
fclose(source);
fclose(listing);
fclose(token);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -