编译原理求解,让我怀疑人生了

img


这个怎么弄啊?尤其是第三小问,真的是把我难住了,想了一天不知道怎么写😭,谁来帮帮我

(1)正规表达式识别微信接龙中订单的词元的正规文法
S -> NUMBER DASH ITEM
ITEM -> NAME QUANTITY UNIT
QUANTITY -> DASH NUMBER
NAME -> 字母+
UNIT -> 份
DASH -> -
NUMBER -> 数字+

在这个正规文法中,S表示订单的开始,NUMBER表示订单序号,DASH表示分隔符,ITEM表示订单项,NAME表示品名,QUANTITY表示数量,UNIT表示单位。

这个正规文法可以帮助你在C语言中使用正则表达式识别微信接龙中订单的词元。只需要将上面的正规文法转换为正则表达式,就可以使用C语言中的正则表达式库(例如pcre库)来匹配和提取微信接龙中订单的词元。
(2)用于语法分析的上下文无关文法:

S -> O | E
O -> 1 N M I | 2 N M I | 3 N M I
N -> 3 | 4 | 5 | ... | n
M -> 0 | 1 | 2 | 3 | 4 | 5 | ... | m
I -> I1 | I2
I1 -> 香蕉数量 份 | 苹果数量 份
I2 -> 香蕉数量 份,苹果数量 份

其中S表示开始符号,O表示订单,N表示序号,M表示客户,I表示订单项。

这个文法定义了一个订单的结构,包括序号、客户和订单项。订单项可以是单个品名和数量,也可以是多个品名和数量,用逗号隔开。

在进行语法分析时,可以使用这个文法来分析输入的微信接龙订单,并判断其是否符合文法规则。
(3)语义计算的翻译模式
我想到的一种方法是使用结构体来表示订单项,包含品名、数量和单位字段。然后可以使用数组或链表来存储所有订单项。

在读取订单信息时,可以使用正则表达式将每个订单项提取出来,并使用字符串函数解析品名、数量和单位。然后将解析出的信息存储在订单项结构体中,并将订单项添加到数组或链表中。

最后,可以遍历数组或链表,对每个订单项进行语义计算,统计每种品名的数量,最终输出结果。

下面是一个可参考的代码:

// 定义订单项结构体
typedef struct order_item {
char name[32]; // 品名
int quantity; // 数量
char unit[32]; // 单位
} OrderItem;

// 定义订单数组
OrderItem orders[100];
int order_count = 0; // 订单数量

// 解析订单项信息
void parse_order_item(char* order_str, OrderItem* item) {
// 使用正则表达式解析订单项信息
// ...

继续完善代码

// 读取订单信息
while (read_order_str(order_str)) {
OrderItem item;
parse_order_item(order_str, &item);
orders[order_count++] = item;
}

// 语义计算
int counts[100] = {0}; // 品名数量
char names[100][32] = {0}; // 品名列表
int name_count = 0; // 品名数量

for (int i = 0; i < order_count; i++) {
int found = 0;
for (int j = 0; j < name_count; j++) {
if (strcmp(orders[i].name, names[j]) == 0) {
counts[j] += orders[i].quantity;
found = 1;
break;
}
}

if (!found) {
strcpy(names[name_count], orders[i].name);
counts[name_count] = orders[i].quantity;
name_count++;
}
}

// 输出结果
for (int i = 0; i < name_count; i++) {
printf("%s 共 %d %s\n", names[i], counts[i], orders[i].unit);
}