自学内容网 自学内容网

PL/0-语法分析器

本文主要按照笔者逻辑思考的顺序进行语法分析部分的说明。如有不明白的部分请见谅。

在拿到词法分析部分的一个又一个的 Token 时,庞大的语法分析让我无法下手,我不知道如何利用这些 Token,也不知道将 PL/0 语言用上下文无关文法描述出来有什么用,但这并不妨碍我们先将上下文无关文法写出来(看懂)😎

上下文无关文法描述的 PL/0 语言:

  • Program → Block .

  • Block → [ConstDecl][VarDecl][ProcDecl] Stmt

    程序块的基本结构是:常量定义、变量定义、过程定义、语句

  • ConstDecl → const ConstDef {, ConstDef} ;
    常量定义

  • ConstDef → ident = number

  • VarDecl → var ident {, ident} ;
    变量定义

  • ProcDecl → procedure ident ; Block ; {procedure ident ; Block ;}
    过程定义

  • Stmt → ident := Exp | call ident | begin Stmt {; Stmt} end | if Cond then Stmt | while Cond do Stmt | ε

    赋值语句、调用语句、begin-end 块语句、判断语句、循环语句

  • Cond → odd Exp | Exp RelOp Exp
    条件表达式

  • RelOp → = | <> | < | > | <= | >=
    关系运算符

  • Exp → [+ | − ] Term {+ Term | − Term}
    表达式

  • Term → Factor {* Factor | / Factor}

  • Factor → ident | number | ( Exp )

  • ident:字母开头的字母 / 数字串

  • number:无符号整数

从上面的文法中我们可以得到以下的信息:

  • 🤔:PL/0 语言有着严格的先后顺序,必须将常量的声明、定义以及变量的声明放在最前面,然后是过程的声明和定义,最后才是语句。
  • 😎:过程里可以嵌套过程的定义,过程里也可以调用(call)其他的过程。
  • 😴:分号的位置很重要,常量和变量声明和定义的最后有;过程名后有;过程体结束后有;语句(stmt)只有在 begin 中的语句中有。
  • 😋:程序最后是以 . 结束的。

有了上述的理解,我们终于知道程序的大概流程了。因为这里我们不用预测分析表,所以对于流程的了解挺重要的。下面将结合流程图展开分析(这里先不着急写代码,一切都理解了写代码其实很快。

程序的入口:

我们进入程序的“大门”,遇到了一个程序体,这里的程序体就像一个黑盒子(函数),我们一头扎进去,最后又会走出来,然后遇到一个 . ,这样程序就结束了。

程序体:

下面我们走进黑盒子中,发现又有许多分支 😵,但我们有一个竖向的“主线”,不妨就沿着主线走一遭。第一个“路口”是 const,我们忍住了没进去;第二个“路口”是 var,我们再次忍住了,因为我们是为了走到最后,而不能误入“歧途”。就这样,我们到了第三个 procedure 以及第四个“语句”,终于没有“路”可以走了,我们走到了尽头。

这一路上,我们遇到了很多“分叉口” – const、var、prodedure 和语句,但我们都不知道里面究竟是什么,它们对我们来说就是一个又一个的黑盒子,没错就是黑盒子,而在之后我们都会定义一个函数来代表黑盒子。这时,你可能感觉到了什么 😳,我们继续往下进行。

语句这个就更容易看出来分了五路,但不同于上面的程序体,语句这五条路,你一次只能选一条!

这样基本的程序结构,我们已经分析完了,但毕竟 talk is cheap. Show me the code 现在写完整的代码还为时尚早,不如用伪代码(可能)代替。

我们从头开始,进入了一个程序之中,并在其中发现了程序体(黑盒)和一个点号。

prog(){
    block();
    match('.');
}

然后是程序体内部,有 const、var 和 procedure 和语句:

block(){
    const();
    var();
    procedure();
    statement();
}

最后是语句,有五个分支:

statement(){
    assign();
    call();
    begin();
    if();
    while();
    // 空就不写了
}

下面就是对于函数体内部的补充了。待续……


原文地址:https://blog.csdn.net/qq_27378595/article/details/143810335

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!