hjwdashuaibi 2023-10-12 01:31 采纳率: 47.4%
浏览 16
已结题

文法中终结符号的集合中的成员如何计算

给定文法G[S]及其非终结符A,FIRST(A)定义为:从A出发能推导出的终结符号的集合(S是文法的起始符号,为非终结符)。对于文法G[S]:(1) S→[L]|a (2)L→L,S|S 其中,G[S]包含的4个终结符号分别为: a , [ ] 则FIRST(S)的成员包括什么( ),这个是我的问题,答案是a、[

对于文法G[S],从S出发推导出[a,a]和a的过程可表示为: S=>[L]=>[L,S]=>[S,S]=>[a,S]=>[a,a] ,S=>a 。所以为啥FIRST()的集合不是a,[],而是a[。

破案了

img

搜夸克给出的是从S出发可推导出以a或[开始的符号串,因此FIRST(S)的成员包括a、[。可是我不懂为什么只取开头

问了c知道给出的是:
求解FIRST(S)的过程如下:

  1. 首先将S能够推导出的所有符号串列举出来:[L]和a。FIRST()中的集合中的具体元素是通过以下规则得出的:
    (1. 如果X是一个终结符号,则FIRST(X) = {X}。
    (2. 如果X是一个非终结符号,则将X能够推导出的所有符号串的FIRST集合合并起来,即FIRST(X) = FIRST(Y1) ∪ FIRST(Y2) ∪ ... ∪ FIRST(Yn),其中Y1, Y2, ..., Yn是X能够推导出的所有符号串。
  2. 对于[L],根据规则2,需要计算(L)。而L又能够推导出L和S,所以需要计算FIRST(L)和FIRST(S)。根据规则1,可以得到FIRST(L) = {a}。对于FIRST(S),根据规则1,可以得到FIRST(S) = {a, [}。
  3. 对于a,根据规则1,可以得到FIRST(a) = {a}。
  4. 将所有计算得到的FIRST集合合并起来,即可得到FIRST(S) = {a, [}。
    对于这个过程我也看的很懵,再去找但是其它地方搜到的只有答案,求答案
  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-10-12 04:06
    关注

    【以下回答由 GPT 生成】

    首先,根据给定的文法G[S],我们可以得出以下推导过程:

    1. S → [L],可以推导出的终结符号是[。
    2. 然后,根据规则(2),L → L, S,可以继续推导出:
    3. L → L, S,可以推导出的终结符号是逗号(,)。
    4. L → S,可以推导出的终结符号是终结符a。
    5. 接下来,我们再次使用规则(2):
    6. L → L, S,可以推导出的终结符号是终结符a。
    7. L → S,可以推导出的终结符号是终结符a。
    8. 继续应用规则(2):
    9. L → L, S,可以推导出的终结符号是终结符a。
    10. L → S,可以推导出的终结符号是终结符a。
    11. L → S,可以推导出的终结符号是终结符[。
    12. L → S,可以推导出的终结符号是终结符]。

    现在,我们找出了S能够推导出的所有终结符号,它们分别是[、,、a和]。根据规则(1)和(2),我们可以得出FIRST(S)的成员应包括[、,、a和]。因此,最终的答案是:

    FIRST(S) = {[, ,, a, ]}。

    如果你需要用C语言编写代码来计算FIRST(S),以下是一个使用简单的递归方法实现的示例代码:

    #include <stdio.h>
    
    #define MAX_SYMBOLS 5
    
    // 判断一个符号是否为终结符
    int isTerminal(char symbol) {
        // 这里假设终结符号集合为[a, [, ], ,],可以根据实际文法进行修改
        char terminals[MAX_SYMBOLS] = {'a', '[', ']', ','};
    
        for (int i = 0; i < MAX_SYMBOLS; i++) {
            if (symbol == terminals[i]) {
                return 1;
            }
        }
    
        return 0;
    }
    
    // 计算非终结符A能够推导出的终结符号集合
    void calculateFirst(char A, char* firstSet, int* setSize) {
        if (isTerminal(A)) {
            // 如果A是终结符,则将A加入到firstSet中
            firstSet[(*setSize)++] = A;
        } else {
            // 如果A是非终结符,则根据产生式规则计算FIRST(A)
            // 这里假设产生式规则为[S → [L]|a, L → L,S|S],可以根据实际文法进行修改
            if (A == 'S') {
                if (!isTerminal('[')) {
                    calculateFirst('[', firstSet, setSize);
                }
                if (!isTerminal('a')) {
                    calculateFirst('a', firstSet, setSize);
                }
            } else if (A == 'L') {
                if (!isTerminal(',')) {
                    calculateFirst(',', firstSet, setSize);
                }
                if (!isTerminal('a')) {
                    calculateFirst('a', firstSet, setSize);
                }
                if (!isTerminal('[')) {
                    calculateFirst('[', firstSet, setSize);
                }
                if (!isTerminal(']')) {
                    calculateFirst(']', firstSet, setSize);
                }
            }
        }
    }
    
    int main() {
        char firstSet[MAX_SYMBOLS];
        int setSize = 0;
    
        calculateFirst('S', firstSet, &setSize);
    
        printf("FIRST(S) = {");
        for (int i = 0; i < setSize; i++) {
            printf("%c", firstSet[i]);
            if (i != setSize - 1) {
                printf(", ");
            }
        }
        printf("}\n");
    
        return 0;
    }
    

    请注意,上述代码只是一个示例,假设了一个简单的终结符号集合和产生式规则。根据实际的文法和终结符号集合,你可能需要进行相应的修改。



    【相关推荐】



    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 10月12日
  • 修改了问题 10月12日
  • 创建了问题 10月12日