0

所以我被分配了这个项目,并且一直在尝试旧的大学,但我对如何去做有点迷茫。这个想法是给你一个 txt 文件,其语法格式为:

  • 五:S、A、B、C
  • 标签
  • 小号:小号
  • 磷:
  • S -> aAaA|aABBA
  • A -> AaaA|$
  • B -> bB|bbC
  • C -> B

这些生产规则不会是唯一经过测试的规则,但这只是一个示例。

所以第一步是读入程序。下一步是删除 Lambda ($) 产生式。最后一步是删除单位产品。

我是......我删除 lambda 产品的方式并不是我认为的最佳方式。

这就是我的做法。

所以首先,使用 getline 读取文件。接下来使用一些循环来遍历文件。

现在在一个数组中,我已经存储了与具有 lambda 产生式的规则相对应的非终结符,所以请记住这一点。

因此,在遍历每个产生式中的每个字符时,检查该字符是否与表示 lambda 产生式的非终结符数组中的一个相同(不包括索引 0,因为那是产生式的开始)

如果您找到匹配项,请标记您所在的索引

所以说你通过S。

S -> a (没问题) s -> aA (好吧有点问题)

而不是写A,不要。跳过它,然后使用另一个循环,打印出该生产规则的剩余部分(即,打印到你打到一个条)所以我们得到 S -> aaA

现在画一个酒吧

S->aaA| 现在将索引返回到该块中的第一个字符,这里是 a。从那里,通过你第一次点击非终端的地方重写字符。

S -> aaA|aA

现在继续循环查找下一个非终结符是 lambda

S -> aaA | aAaA(我们在这里)

画条

S -> aaA | 啊啊|

回到起点,继续

S -> aaA | 啊啊| 啊啊啊

继续阅读语法并输出每个字符并重复此过程以获得

S -> aaA | 啊啊| 啊啊啊| aABB | aBBA | aABBA

在所有代码的末尾,我有两个循环来检查语法中的原始条(当我这样做时,我将它们替换为!),然后在最后输出具有所有 lambda 产品作为 lambdas 给出的形式

S -> aaA | 啊啊| 啊啊啊| 啊 | aABB | aBBA | aABBA | aBB

我将在此处包含代码,但请注意,... 这很粗糙。它很粗糙,我实际上无法让它很好地落在这里的编码块下,所以我要链接它。

代码

我很欣赏你将如何进行这个项目的任何想法,或者我是否在做一些公然错误的事情。

该代码当前抛出了一些错误(我很确定这是我在某处读取一些空字符的原因),但如果你忽略它们,它会吐出来控制台正确的事情......主要是。

感谢您的帮助,感谢您花时间阅读所有这些混乱。

4

1 回答 1

1

这是我推荐的架构:

  1. 定义语法的元语法(您正在使用的语法产生的语法)
  2. 为该元语法编写一个简单的分词器
  3. 编写基于元语法的手写递归体面解析器,对每个输入语法产生式进行解析并创建语法树
  4. 根据 CNF 规则操作语法树
  5. 从修改后的语法树生成输出。

元语法示例:

production:
    nonterminal ':' alternatives

alternatives:
    alternative,
    alternative ',' alternatives

alternative:
    symbols

symbols:
    symbol,
    symbol symbols

symbol:
    terminal,
    nonterminal,
    '$'

etc..
于 2012-11-27T01:23:21.873 回答