C语言编写 词法分析器
时间: 2024-02-10 07:43:36 浏览: 95
词法分析器是编译器中的一个重要组成部分,它负责将源代码中的字符流转换成有意义的单词(token)流。在C语言中,我们可以使用自动机(DFA)来实现词法分析器。
以下是一个简单的C语言词法分析器的实现:
```c
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
typedef enum {
NONE,
IDENTIFIER,
KEYWORD,
OPERATOR,
DELIMITER,
CONSTANT
} TokenType;
typedef struct {
TokenType type;
char value[20];
} Token;
char input[1000];
int input_len = 0;
int pos = 0;
bool is_keyword(const char* str) {
const char* keywords[] = {
"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"
};
int n = sizeof(keywords) / sizeof(keywords[0]);
for (int i = 0; i < n; i++) {
if (strcmp(str, keywords[i]) == 0) {
return true;
}
}
return false;
}
bool is_operator(char c) {
const char* operators = "+-*/%=&|><!^~";
int n = strlen(operators);
for (int i = 0; i < n; i++) {
if (c == operators[i]) {
return true;
}
}
return false;
}
bool is_delimiter(char c) {
const char* delimiters = "(){}[],;:";
int n = strlen(delimiters);
for (int i = 0; i < n; i++) {
if (c == delimiters[i]) {
return true;
}
}
return false;
}
bool is_constant(char* str) {
int len = strlen(str);
if (len == 0) {
return false;
}
for (int i = 0; i < len; i++) {
if (!isdigit(str[i])) {
return false;
}
}
return true;
}
Token get_next_token() {
Token token;
token.type = NONE;
strcpy(token.value, "");
if (pos >= input_len) {
return token;
}
while (isspace(input[pos])) {
pos++;
}
if (isalpha(input[pos])) {
int i = 0;
while (isalnum(input[pos])) {
token.value[i++] = input[pos++];
}
token.value[i] = '\0';
if (is_keyword(token.value)) {
token.type = KEYWORD;
} else {
token.type = IDENTIFIER;
}
} else if (is_operator(input[pos])) {
token.type = OPERATOR;
token.value[0] = input[pos++];
token.value[1] = '\0';
if (input[pos] == '=') {
token.value[1] = input[pos++];
token.value[2] = '\0';
}
} else if (is_delimiter(input[pos])) {
token.type = DELIMITER;
token.value[0] = input[pos++];
token.value[1] = '\0';
} else if (isdigit(input[pos])) {
int i = 0;
while (isdigit(input[pos])) {
token.value[i++] = input[pos++];
}
token.value[i] = '\0';
if (input[pos] == '.') {
token.type = CONSTANT;
token.value[i++] = input[pos++];
while (isdigit(input[pos])) {
token.value[i++] = input[pos++];
}
token.value[i] = '\0';
} else {
token.type = CONSTANT;
}
} else {
pos++;
}
return token;
}
int main() {
printf("Enter input:\n");
fgets(input, sizeof(input), stdin);
input_len = strlen(input);
while (pos < input_len) {
Token token = get_next_token();
if (token.type != NONE) {
printf("%s: %s\n", token.value, token.type == KEYWORD ? "keyword" :
token.type == IDENTIFIER ? "identifier" :
token.type == OPERATOR ? "operator" :
token.type == DELIMITER ? "delimiter" :
token.type == CONSTANT ? "constant" : "");
}
}
return 0;
}
```
该程序将读取用户输入的C语言源代码,并输出词法分析结果。
代码中定义了5种令牌类型:IDENTIFIER(标识符),KEYWORD(关键字),OPERATOR(运算符),DELIMITER(分隔符)和CONSTANT(常量)。
`is_keyword`函数用于判断一个字符串是否为C语言中的关键字。
`is_operator`函数用于判断一个字符是否为C语言中的运算符。
`is_delimiter`函数用于判断一个字符是否为C语言中的分隔符。
`is_constant`函数用于判断一个字符串是否为C语言中的常量。
`get_next_token`函数用于获取下一个令牌。该函数首先跳过所有的空格字符。如果当前字符是字母,则将之后的所有字母和数字都读入到字符串中,然后判断该字符串是否为关键字或标识符。如果当前字符是运算符,则将该字符和之后的一个字符(如果有的话)读入到字符串中,并判断该字符串为运算符。如果当前字符是分隔符,则将该字符读入到字符串中,并判断该字符串为分隔符。如果当前字符是数字,则将之后的所有数字都读入到字符串中,并判断该字符串是否为常量。
在`main`函数中,我们使用`fgets`函数读取用户输入的源代码,并逐个获取令牌并输出。
阅读全文