使用Java语言编写PL/0编译程序的词法分析程序。
时间: 2024-02-09 14:10:57 浏览: 265
基于Java实现的针对PL0文法的编译器【100011386】
下面是一个简单的 Java 词法分析程序,可以识别 PL/0 语言的关键字、标识符、数字和符号。
```java
import java.io.*;
public class Lexer {
private static final int LETTER = 0;
private static final int DIGIT = 1;
private static final int UNKNOWN = 99;
private static final int MAX_LEXEME_LEN = 100;
private static final int EOF = -1;
private static final int INT_LIT = 10;
private static final int IDENT = 11;
private static final int ASSIGN_OP = 20;
private static final int ADD_OP = 21;
private static final int SUB_OP = 22;
private static final int MULT_OP = 23;
private static final int DIV_OP = 24;
private static final int LEFT_PAREN = 25;
private static final int RIGHT_PAREN = 26;
private static final int SEMICOLON = 27;
private static final int PERIOD = 28;
private static final String[] RESERVED_WORDS = {
"begin", "call", "const", "do", "end",
"if", "odd", "procedure", "read", "then",
"var", "while", "write"
};
private static final int[] RESERVED_WORD_TOKENS = {
21, 22, 23, 24, 25,
26, 8, 27, 28, 29,
30, 31, 32
};
private static int charClass;
private static char[] lexeme = new char[MAX_LEXEME_LEN];
private static char nextChar;
private static int lexemeLen;
private static int token;
private static FileInputStream fis;
private static void addChar() {
if (lexemeLen + 1 >= MAX_LEXEME_LEN) {
System.err.println("Error: lexeme is too long.");
System.exit(1);
}
lexeme[lexemeLen++] = nextChar;
lexeme[lexemeLen] = '\0';
}
private static void getChar() {
try {
int c = fis.read();
if (c != EOF) {
nextChar = (char) c;
if (Character.isLetter(nextChar)) {
charClass = LETTER;
} else if (Character.isDigit(nextChar)) {
charClass = DIGIT;
} else {
charClass = UNKNOWN;
}
} else {
charClass = EOF;
}
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
}
private static void getNonBlank() {
while (Character.isWhitespace(nextChar)) {
getChar();
}
}
private static int lookup(char[] s) {
for (int i = 0; i < RESERVED_WORDS.length; i++) {
if (RESERVED_WORDS[i].equals(new String(s))) {
return RESERVED_WORD_TOKENS[i];
}
}
return IDENT;
}
private static int lex() {
lexeme = new char[MAX_LEXEME_LEN];
lexemeLen = 0;
getNonBlank();
switch (charClass) {
case LETTER:
addChar();
getChar();
while (charClass == LETTER || charClass == DIGIT) {
addChar();
getChar();
}
token = lookup(lexeme);
break;
case DIGIT:
addChar();
getChar();
while (charClass == DIGIT) {
addChar();
getChar();
}
token = INT_LIT;
break;
case UNKNOWN:
switch (nextChar) {
case ':':
addChar();
getChar();
if (nextChar == '=') {
addChar();
getChar();
token = ASSIGN_OP;
} else {
token = UNKNOWN;
}
break;
case '+':
addChar();
getChar();
token = ADD_OP;
break;
case '-':
addChar();
getChar();
token = SUB_OP;
break;
case '*':
addChar();
getChar();
token = MULT_OP;
break;
case '/':
addChar();
getChar();
token = DIV_OP;
break;
case '(':
addChar();
getChar();
token = LEFT_PAREN;
break;
case ')':
addChar();
getChar();
token = RIGHT_PAREN;
break;
case ';':
addChar();
getChar();
token = SEMICOLON;
break;
case '.':
addChar();
getChar();
token = PERIOD;
break;
default:
addChar();
getChar();
token = UNKNOWN;
break;
}
break;
case EOF:
token = EOF;
lexeme[0] = 'E';
lexeme[1] = 'O';
lexeme[2] = 'F';
lexeme[3] = '\0';
break;
}
System.out.printf("Token: %d, Lexeme: %s\n", token, new String(lexeme));
return token;
}
public static void main(String[] args) {
if (args.length != 1) {
System.err.println("Usage: Lexer <input_file>");
System.exit(1);
}
try {
fis = new FileInputStream(args[0]);
} catch (FileNotFoundException e) {
e.printStackTrace();
System.exit(1);
}
getChar();
while (token != EOF) {
lex();
}
}
}
```
使用该词法分析程序,可以通过以下命令执行:
```sh
javac Lexer.java
java Lexer <input_file>
```
其中 `<input_file>` 是要分析的 PL/0 源代码文件。程序会输出每个 Token 的类型和对应的词素。
阅读全文