知识大全 Straight-Line编程语言的分析和解释

Posted 表达式

篇首语:孙竹新添绿玉枝,稚禽学习绕檐飞。动中会取归根意,雨过白云横翠微。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 Straight-Line编程语言的分析和解释相关的知识,希望对你有一定的参考价值。

Straight-Line编程语言的分析和解释  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  这里介绍一个极其简单的编程语言的部分实现 即Straight Line编程语言 没有循环和if else的结构

  Straight Line语言的语法(Grammar)

  Stm ::= Stm; Stm 

  CompoundStm

  Stm ::= id := Exp

  AssignStm

  Stm ::= print(ExpList)

  PrintStm

  ExpList ::= Exp ExpList

  PairExpList

  ExpList ::= Exp

  LastExpList

  Exp ::= id

  IdExp

  Exp ::= num

  NumExp

  Exp ::= Exp Binop Exp

  OpExp

  Exp ::= (Stm Exp)

  EseqExp

  Binop::= + | | * | /

  Arithmetic Operators

    Straight Line语言的语义如下 s ;s 先执行s 再执行s i := e 计算e的值 保存在变量i中 print(e e en)打印出e e en的值 用空格隔离 结尾换行 (Stm Exp)类似C中的逗号表达式 先执行Stm 为了Stm的Side Effect 然后计算Exp 返回Exp的值 举个例子       a := + ; b := (print (a a ) *a); print(b)输出                    怎样在编译器中表达Straight Line语言的程序呢?Straight Line程序是一个树状结构 可以用树状的数据结构来表示 节点表示程序的不同单元 从Straight Line语言的语法我们可以推出怎样在Java中用类的结构表达Straight Line的程序 每个符号对应一个抽象类 比如Stm抽象类对应Stm符号 每条语法规则用一个具体类的构造函数实现 比如CompoundStm的右边有两个Stm组成 那么继承自Stm的CompoundStm的一个构造函数的参数是两个Stm 这两个Stm保存在CompoundStm的属性里 abstract class Stm abstract class Exp abstract class ExpList class CompoundStm extends Stm     Stm stm  stm ;    CompoundStm(Stm s  Stm s )  stm  = s ; stm  = s ; class AssignStm extends Stm     String id; Exp exp;    AssignStm(String i  Exp e)  id = i; exp = e; class PrintStm extends Stm     ExpList exps;    PrintStm(ExpList e)  exps = e; class PairExpList extends ExpList     Exp head; ExpList tail;    PairExpList(Exp h  ExpList t)  head = h; tail = t; class LastExpList extends ExpList     Exp exp;    LastExpList(Exp e)  exp = e; class IdExp extends Exp     String id;    IdExp(String i)  id = i; class NumExp extends Exp     int num;    NumExp(int n)  num = n; class OpExp extends Exp     final static int Plus =   Minus =   Times =   Div =  ;    Exp left  right;     int oper;    OpExp(Exp l  int o  Exp r)  left = l; oper = o; right = r; class EseqExp extends Exp     Stm stm; Exp exp;    EseqExp(Stm s  Exp e)  stm = s; exp = e;  Stm testprog = new CompoundStm(new AssignStm( a  new OpExp(            new NumExp( )  OpExp Plus  new NumExp( )))  new CompoundStm(            new AssignStm( b  new EseqExp(new PrintStm(new PairExpList(                    new IdExp( a )  new LastExpList(new OpExp(new IdExp( a )                             OpExp Minus  new NumExp( )))))  new OpExp(                    new NumExp( )  OpExp Times  new IdExp( a ))))             new PrintStm(new LastExpList(new IdExp( b )))));    在这里 我要略过Parsing 从上面这段树状结构开始 对Straight Line程序做分析和解释 分析是指分析一个Straight Line程序的属性 比如int maxargs(Stm stm)分析stm中的Print表达式的最大参数个数 解释就是执行一个Straight Line程序 下面我们来实现maxargs和Straight Line程序的一个解释器 我们采用一种没有Side Effect的实现方式 也就是变量和对象属性除了在构造时不能改变 对局部变量用定义时即赋值的方式 首先是maxargs 我们先写测试代码 package tiger slpl;import junit framework TestCase;public class TestCountMaxPrintStmArgs extends TestCase     public TestCountMaxPrintStmArgs(String m)         super(m);        public void testMaxargs()         CountMaxPrintStmArgs counter = new CountMaxPrintStmArgs();        assertEquals(  counter maxargs(TestProg testprog));    TestProg testprog即是上面给出的程序 print表达式参数个数的最大值是 现在实现maxargs package tiger slpl;import static java lang Math max;/** * This Interpreter is too in functional style <br> *         no assignment<br> *         definition with initialization<br>  *             <code>int i =  ;</code> introduces a new variable  *  * @author pan */class CountMaxPrintStmArgs     /**     * Entry Point     */    int maxargs(Stm stm)         return _maxargs(stm);        /*     * Because ExpList can occurs only for PrintStm      * That is the same to count length of ExpList     * but here I use another approach to count only for     * PrintStm     *      * if you want to avoid instanceof  then you can     * pack maxargs methods in classes e g  Stm     */    private int _maxargs(Stm stm)         if (stm instanceof CompoundStm)             CompoundStm cstm = (CompoundStm) stm;            return max(_maxargs(cstm stm )  _maxargs(cstm stm ));         else if (stm instanceof AssignStm)             AssignStm astm = (AssignStm) stm;            return _maxargs(astm exp);         else  // Then it can be only PrintStm            PrintStm pstm = (PrintStm) stm;            return max(countargs(pstm exps)  _maxargs(pstm exps));                private int _maxargs(ExpList exps)         if (exps instanceof PairExpList)             PairExpList pexps = (PairExpList) exps;            return max(_maxargs(pexps head)  _maxargs(pexps tail));         else  // Then it can be LastExpList            LastExpList lexps = (LastExpList) exps;            return _maxargs(lexps exp);                private int _maxargs(Exp exp)         if (exp instanceof IdExp)            return  ;        else if (exp instanceof NumExp)            return  ;        else if (exp instanceof OpExp)             OpExp oexp = (OpExp) exp;            return max(_maxargs(oexp left)  _maxargs(oexp right));         else  // Then it can be EseqExp            EseqExp eexp = (EseqExp) exp;            return max(_maxargs(eexp stm)  _maxargs(eexp exp));                private int countargs(ExpList exps)         if (exps instanceof LastExpList)            return  ;        else  // Then it is a PairExpList            PairExpList pexps = (PairExpList) exps;            return   + countargs(pexps tail);                这里解释一下int _maxargs(Stm stm) 一个Stm可以是CompoundStm AssignStm或者PrintStm 如果是CompoundStm 那么_maxargs(Stm stm)等于stm下两个子Stm的maxargs的较大值 如果是AssignStm 等于AssignStm的表达式的maxargs 如果是PrintStm 那么是PrintStm的参数个数(countargs数PrintStm的参数个数) 或者ExpList的maxargs 看哪个更大 其他的函数的解释也是类似的 对照Straight Line语言的语法不难理解     上面的maxargs的实现中用了很多instanceof 另外的一种实现方式可以把各个maxargs放在各自的类下 比如CompoundStm maxargs计算一个CompoundStm的maxargs 这种方式的一个缺点是 将分析算法放在模型结构类中 如果有很多种分析要做 模型类就比较混乱 可以使用Visitor设计模式 对不同的算法定义不同的Visitor类 兼顾前面两种方式的优点 当然这是一篇有关编译技术的随笔 代码采用最容易理解的实现方式 cha138/Article/program/Java/hx/201311/26757

相关参考

知识大全 谁可以用通俗易懂的语言解释“银行汇票”和“支票”的定义

谁可以用通俗易懂的语言解释“银行汇票”和“支票”的定义?“银行汇票”的意思就是到了付款时间,不管你公司在银行账上有没有钱,只要银行看到你公司开出的“银行汇票”,银行无条件地向持票人付款.“支票”的意思

知识大全 /德语/请用最通俗易懂的语言解释一下什么是强变化和弱变化

/德语/请用最通俗易懂的语言解释一下什么是强变化和弱变化?德语里,动词要根据人称进行词尾的变化,英语中也有,但是德语较为复杂些。强变化就是不规则变化,弱变化就是规则变化。例如PräsensPräter

知识大全 谁来帮用通俗易懂的语言解释下java的反射机制

谁来帮用通俗易懂的语言解释下java的反射机制JavaReflactioninAction有这么一句话,可以解释。反射是运行中的程序检查自己和软件运行环境的能力,它可以根据它发现的进行改变。通俗的讲就

知识大全 一道初三化学题 请用通俗易懂点的语言解释一下,正确答案和解题思路都说一下 谢谢

一道初三化学题请用通俗易懂点的语言解释一下,正确答案和解题思路都说一下谢谢答案是A,思路是这样的,所取物质的碳酸根全部转化为二氧化碳,根据二氧化碳相对分子质量和实际质量列出比例,就是44:4.4,完整

知识大全 比特币课程是什么意思,能否用通俗易懂的语言解释一下

比特币课程是什么意思,能否用通俗易懂的语言解释一下比特币是一个共识网路,促成了一个全新的支付系统和一种完全数字化的货币。它是第一个去中心化的对等支付网路,由其使用者自己掌控而无须中央管理机构或中间人。

知识大全 请用比较通俗易懂的语言解释一下何谓审计重要性

请用比较通俗易懂的语言解释一下何谓审计重要性?重要性水平过低,也就是说要求低,门槛低,只要不出大漏子,就没事,相应的就减少你的审计工作量,自然提长了审计效率。但是也增加了审计风险重要性水平过高正好和其

保险合同条款解释原则的普通词意原则

保险合同条款应当通过其使用的语言文字的基本、自然、一般和通常的语义加以理解,其所使用的语言文字的含义,是一个具有通常智力水平的普通人所理解的含义,应当以普通人使用语言文字所理解的含义解释其内容。

知识大全 浅析VB6语言脚本解释器

学习笔记:浅析VB6语言脚本解释器  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  讨论如何让自己

知识大全 能不能请高手用最通俗易懂的语言解释下英语的“介宾短语”

能不能请高手用最通俗易懂的语言解释下英语的“介宾短语”?由介词加上后面的名词、代词或名词短语组成。介词+宾语=介宾短语如bybus,onthedesk,onfoot能不能用通俗易懂的语言解释下圣经中《

知识大全 概率密度函式该怎么理解,能否不要用数学语言而用通俗的语言解释一下呢

概率密度函式该怎么理解,能否不要用数学语言而用通俗的语言解释一下呢?谢谢!可以这样理解假如一次考试,30人参加,90分3人,90以上10人,概率密度就是90分的概率即,3/30概率分布是90分及以上的