以下挑战要求您熟悉正式的解析器理论。如果您不知道问题的含义是因为您不知道该问题的含义,那么很多大学课程都涵盖了上下文无关的语法和第一套/跟随套。
我可以推荐此斯坦福课程,特别是讲义08和09(第7页)。我还从这些讲义中提取了备忘单 - 我建议尝试此挑战的任何人都阅读它。
编写一个程序或函数,该程序或函数在无上下文语法的情况下可以找到每个非终结符的后续集合。非正式地,非终结符的跟随集是一组终结符和$
(表示输入结束),您可以在该终结符之后的有效句子中找到它们。
输入以单个可打印ASCII字符串或可打印ASCII行的数组形式给出。您可以以任何合理的格式输出集合,使用$
(作为文字输出或集合中的字符串等)指示输入的结束。您可以根据以下格式假定输入始终有效。
上下文无关的语法以非常简化的方式给出。每条生产线包含一个生产。每个产品都是用空格分隔的符号列表。终端是一串用撇号(例如'**'
)括起来的字符。为了简单起见,您可以假定终端不包含空格,但是如果您的程序允许的话,那会很好。非终结符可以是任何不包含空格或的字符串$
。空生成(通常用ε表示)只是一条仅包含左侧非终结符的行。第一行是定义开始符号的生产。
例如,以下语法:
S→aSa | bSb | ε
将给出为:
S 'a' S 'a'
S 'b' S 'b'
S
输入/输出示例:
In:
S 'a' S 'a'
S 'b' S 'b'
S
Out:
S {'a', 'b', $}
In:
S A B C
A 'a'
A C 'b'
A
B C
B 'd' A
B
C 'e'
C 'f'
Out:
S {$}
A {'d', 'e', 'f'}
B {'e', 'f'}
C {'b', 'e', 'f', $}
In:
Start Alice Bob
Alice Charlie 'a'
Alice
Bob Bob 'a' Alice Charlie
Bob '!!!'
Charlie 'b'
Charlie
Out:
Start {$}
Alice {'a', '!!!', 'b', $}
Bob {'a', $}
Charlie {'a', $}
以字节为单位的最短代码获胜。