编译原理

来源:互联网 发布:css js 格式化工具 编辑:程序博客网 时间:2024/04/26 04:16

公共做因子:  在文法的产生式中, 非终结符的候选式有相同的前缀

提取公共左因子:就是,把左因子写出来,然后用一个非终结符代替原来的不同项

消除左递归: 实际上就是改成右递归的形式, 首先把终结符提前,用新的非终结符代替原来的左递归的项, 以这个新的非终结符构造一个包含空串的又递归

文法 P→Pα|β   改变后:

P→bP

PαP’


消除间接左递归


消除可能的左递归:  

for i:=1to n do

   begin

      for j:=1to i-1 do       

         把形如Ai→Aja的产生式改写为δδ

              Ai→δ1a|δ2a|…|δka

       消除Ai产生式可能的直接左递归

    end

上面是一个非常复杂的东西, 教授的东西.  用一句简单的话概括就是, 把排列之后的非终结符, 一次只让一个非总结符在产生式中消失

比如文法

      S→Qc│c

      Q→Rb│b

      R→Sa│a


1, 按SQR排列,让他们消失

     ①消除S:    Q→Rb | b;

                          R→Qca | ca | a;

     ②消除Q:   R→ Rbca│bca│ca│a

     这里已经把间接左递归消除了, 然后消除直接左递归就可以了.

       R→ bcaR’ │ caR’ │aR

       R’→ bcaR’ │ε

      文法产生的语言:(bca|ca|a)(bca)*bc|bc|c    (这个本人看不懂),好像看懂了, 是不是因为产生式S,   看文法, S是可以产生bc , 和c的

2. RQS排列

   

       R→Sa│a

       Q→Sab│ab│b

       S→Sabc│abcbc│c


编译原理实验

很奇葩的错误:

error: jump to case label [-fpermissive]|

解决:

int main()
{
    int a =0;
    switch(a)
    {
        case 0: int b = 0;break;
        case 1: break;
        default:break;
    }
    return 0;
}

编译器提示错误:
testswitch.cpp: In function ‘int main()’:
testswitch.cpp:9: error: jump to case label
testswitch.cpp:8: error:   crosses initialization of ‘int b’
testswitch.cpp:10: error: jump to case label
testswitch.cpp:8: error:   crosses initialization of ‘int b’

出现这样的提示,你很有可能在某个case标记中定义了局部变量,而后面还有其他的case标记或者default语句。。比如说这里的整形变量b。

看看编译器提示的信息 cross initialization of int b, 什么意思呢, 就是说跳过了变量的初始化,仔细想想,确实是这样,我们在case 0 中定义了变量b,在这个程序中,直到遇到switch的“}”右花括号,b的作用域才终结,也就是说 在case 1 和 default 分支中 变量b依然是可以访问的。考虑这样一种情况,如果switch匹配了case 1,这样case 0的代码被跳过了,那么b就没有定义,如果此时在case 1的代码中访问了b,程序会崩溃的。如果谁也不匹配,执行default也会有同样的危险。

知道了错误的原因,解决起来就很简单了

1,将case 0 标记 的代码用 {}括起来,这样b的作用域在这个花括号内。在其他的case 标记中不能访问。

2. 将 变量b放在 switch外面 定义。



怎么在string类型中添加一个字符

解决:




F:\codeblock\lexanalyze\Table.h|10|warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11 [enabled by default]|



默认参数的错误

F:\codeblock\lexanalyze\LexAnalyze.h||In constructor 'LexAnalyze::LexAnalyze(std::string, std::string)':|
F:\codeblock\lexanalyze\LexAnalyze.h|20|error: expected '{' at end of input|
F:\codeblock\lexanalyze\LexAnalyze.cpp|6|error: redefinition of 'LexAnalyze::LexAnalyze(std::string, std::string)'|
F:\codeblock\lexanalyze\LexAnalyze.h|20|error: 'LexAnalyze::LexAnalyze(std::string, std::string)' previously defined here|
||=== Build finished: 3 errors, 0 warnings (0 minutes, 0 seconds) ===|

解决:




碰到大写标识符: