编译原理 | 课程设计 — Lex 和 Yacc的使用

第1关 — 碱基序列里特定碱基比例的计算

1、任务描述

双链DNA分子中,G、C碱基对所占比例越高,其稳定性越强。编写一个lex描述文件,计算指定碱基序列里G、C碱基的比例。

2、编程要求

完成上述编程任务,将C语言源程序复制粘贴到右侧代码编辑器,点击“评测”按钮,运行程序,系统会自动进行结果对比。

3、测试说明

平台会对你编写的代码进行测试:

测试输入:ACGTTGATCGGAATCTTCGT 预期输出:0.450

测试输入:TTACGGTACCAATGCTAATGCCTA 预期输出:0.417

4、代码

#include <stdio.h>
#include <string.h>

int main()
{
    char dna[100];
    scanf("%s", dna);

    int length = strlen(dna); 
    int gcCount = 0; 
    for(int i = 0; i < length; i++)
    {
        if(dna[i] == 'G' || dna[i] == 'C') 
            gcCount++;
    }

    double ratio = (double)gcCount / length; 
    printf("%.3f", ratio);
    return 0;
}

第2关 — 文本串里单词、数字和符号的识别

1、任务描述

编写一个lex描述文件,识别出指定文本串里的单词、数字和符号(空格不作处理)。

2、编程要求

完成上述编程任务,将C语言源程序复制粘贴到右侧代码编辑器,点击“评测”按钮,运行程序,系统会自动进行结果对比。

3、测试说明

平台会对你编写的代码进行测试:

测试输入:

using namespace std;
int main()
{
    int year = 2022;
    cout << "hello" << endl;
    return 0;
}

预期输出:

using 单词
namespace 单词
std 单词
; 符号
int 单词
main 单词
( 符号
) 符号
{ 符号
int 单词
year 单词
= 符号
2022 数字
; 符号
cout 单词
< 符号
< 符号
" 符号
hello 单词
" 符号
< 符号
< 符号
endl 单词
; 符号
return 单词
0 数字
; 符号
} 符号

4、代码

#include<stdio.h>
#include<string.h>
#define   maxn 10000

char str[maxn];
void fun(char str[]);
int main() {
	int i = 0;
	while ((str[i] = getchar()) != EOF) {
		i++;
	}
	str[i] = '\0';
	fun(str);
	return 0;
}

void fun(char str[]) {
	for (int j = 0; str[j] != '\0'; j++) {
	
		if (str[j] >= '0' && str[j] <= '9') {
			while (str[j] >= '0' && str[j] <= '9') {
				putchar(str[j]);
				j++;
			}
			j--;
			printf(" 数字\n");
			continue;
		} 
		if ((str[j] >= 'a' && str[j] <= 'z') || (str[j] >= 'A' && str[j] <= 'Z')){
			while ((str[j] >= 'a' && str[j] <= 'z') || (str[j] >= 'A' && str[j] <= 'Z')){
				putchar(str[j]);
				j++;
			}
			j--;
			printf(" 单词\n");
			continue;
		} 
		if (str[j] == ' '||str[j] == '\n'||str[j]=='	'){
			continue;
		} 
		putchar(str[j]);
		printf(" 符号\n");
					
	}

}

第3关 — 简易计算器的实现

1、任务描述

编写一个yacc描述文件,实现具有加法和乘法功能的计算器。

2、编程要求

完成上述编程任务,将C语言源程序复制粘贴到右侧代码编辑器,点击“评测”按钮,运行程序,系统会自动进行结果对比。

3、测试说明

平台会对你编写的代码进行测试:

测试输入:5*7+2 预期输出:37

测试输入:9+3*6 预期输出:27

4、代码

#include "task1-3.tab.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int calculate(int a, int b, char op) {
    switch(op) {
        case '+':
            return a + b;
        case '-':
            return a - b;
        case '*':
            return a * b;
        case '/':
            if (b != 0) return a / b;
            else return 0;
        default:
            return 0;
    }
}

int calculate_expression(char** s) {
    char op[2];
    int num, stack[100], top = -1;

    while (**s && **s != ')') {
        if (isdigit(**s)) {
            sscanf(*s, "%d", &num);
            stack[++top] = num;

            while (isdigit(**s))
                (*s)++;
        }

        if (**s == '+' || **s == '-' || **s == '*' || **s == '/') {
            sscanf(*s, "%s", op);

            if ((*op == '*' || *op == '/') && isdigit(*(*s+1))) {
                int nextNum;
                sscanf(*s+1, "%d", &nextNum);
                stack[top] = calculate(stack[top], nextNum, *op);

                while (isdigit(*(*s+1)))
                    (*s)++;
            }
            else if (top > 0) {
                int right = stack[top--];
                int left = stack[top--];
                stack[++top] = calculate(left, right, *op);
            }
        }

        if (**s == '(') {
            (*s)++;
            stack[++top] = calculate_expression(s);
            (*s)++;
        }

        (*s)++;
    }

    while (top > 0) {
        int right = stack[top--];
        int left = stack[top--];
        stack[++top] = calculate(left, right, '+');
    }

    return stack[0];
}

int calculate_expression_with_parentheses(const char* expression) {
    char* s = (char*)expression;
    return calculate_expression(&s);
}

int main() {
    char expression[100];
    fgets(expression, 100, stdin);
    printf("%d\n", calculate_expression_with_parentheses(expression));
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sun80760/article/details/131078490