• 语法制导翻译


    语法制导翻译

    • 编译器在做语法分析的过程中,除了回答程序语法是否合法外,还必须完成后续工作
      • 可能的工作包括(但不限于)
        • 类型检查
        • 目标代码生成
        • 中间代码生成
        • (dots)
    • 这些后续的工作一般可通过语法制导的翻译完成

    基本思想

    • 给每条产生式规则附加一个语义动作
      • 一个代码片段
    • 语义动作在产生式“归约”时执行
      • 即当 右部 分析完毕时刻
      • 右部 的值计算 左部 的值
      • 自顶向下分析和自底向上分析采用的技术类似
        • 接下来重点讨论在自底向上的技术中的语法制导翻译

    LR 分析中的语法制导翻译

    图片

    示例

    图片

    首先创建一个 .y 文件:

    %{
    
    #include <stdio.h>
    
    #include <stdlib.h>
    
    int yylex();
    
    void yyerror();
    
    %}
    
    
    %left '+'
    
    
    %%
    
    
    lines: line
    
         | line lines
    
    ;
    
    
    line: exp'
    ';
    
    
    exp: n
    
       | exp '+' exp
    
    ;
    
    
    n: '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '0';
    
    
    %%
    
    
    int yylex()
    
    {
    
            return getchar();
    
    }
    
    
    void yyerror(char *s)
    
    {
    
            fprintf(stderr, "%s
    ", s);
    
            return;
    
    }
    
    
    int main(int argc, char ** argv)
    
    {
    
            yyparse();
    
            return 0;
    
    }
    

    在上面的代码中附加几个语义动作,该语义动作将在产生时进行规约的时候执行。

    语义动作使用 {} 括起来,其中 $$ 表示产生式左部, $n 表示产生式有部的第 n 个元素。

    图片

    然后使用 bisongcc 编译运行程序,就可以发现每次完成规约之后遇到换行符 之后就会直接在屏幕打印输出表达式的值。

    图片

    实现原理

    图片

    if (action[s, t] == "ri") {
        ai  // 执行附加语义动作
        pop(βi);
        state s' = stack[top];
        push(X);
        push(goto[s', X]);
    }
    

    在分析栈上维护三元组: <symbol, value, state> 其中 symbol 是终结符或非终结符, valuesymbol 所拥有的值, state 是当前的分析状态。

    图片

  • 相关阅读:
    Redis3.0.1 Stable版本的集群部署(Mac)
    Maven的包依赖冲突可引发java.lang.IncompatibleClassChangeError错误
    Key/Value存储系统etcd的特性
    实时消息平台NSQ的特性
    StringIO函数
    对文件内容进行迭代
    基本文件方法
    打开文件
    正则表达式知识点汇总
    编译
  • 原文地址:https://www.cnblogs.com/geekfx/p/13930185.html
Copyright © 2020-2023  润新知