龙书学习,练习题记录

7/3

1.1.1 1.1.2 编译器将源程序编译成目标程序,执行时,不再需要编译,效率很高,但在不同的平台需要重新编译成可执行文件。解释器一边运行一边解释源代码,可以实现跨平台的编码,但其效率低于编译器。由于解释器逐条执行语句,其检查错误的能力强于编译器。

1.1.3 汇编语言更容易输出和调试,编译器产生汇编语言可以让编译器的设计本身更专注,将其他的工作交给汇编器。

1.1.4 c语言牛逼呀。。。简单易理解,方便输出调试。

1.1.5 汇编器类似于编译器,将汇编程序作为源程序,输出机器代码。


1.3.1 略


1.6.1 w=13 x=11 y=13 z=11

1.6.2 w=9 x=7 y=13 z=11

1.6.3 int w B1-B3-B4 

         int x B1-B2-B4

         int y B1-B5

         int z B1-B2-B5

         int x B2-B3

         int z B2

         int w B3

         int x B3

         int w B4

         int x B4

         int y B5

         int z B5

1.6.4 3 2


2.2.1  t->aa+

         s->ta*

         r->s

                                   s

                        t         a         *

                a     a     +


        +*后缀表达式

2.2.2 1) 0n1n   n>=1

        2) +-前缀表达式

        3) 一堆匹配括号

        4) 由成对a,b组成的串或空串

        5)  以a为元素,具有合并 连接 闭包 括号运算

2.2.3 3 4 5

2.2.4 

      1)expr->expr term + | expr term - | term

         term->term factor * | term factor / | factor

         factor->digit | (expr)

      2)stmt->stmt , id | id

      3)stmt-> id , stmt | id

      4)expr -> expr + term | expr - term | term

         term -> term * factor | term / factor | factor

         factor->id | digit | (expr)

      5)expr -> expr + term | expr - term | term

         term -> term * factor | term / factor | signedfactor

         signedfactor-> + factor | - factor 

         factor -> id digit | (expr)

2.2.5 11 十进制是 3

         1001 十进制是 9

         num 0 ,如果num被3整除,这个操作相当于十进制乘2,自然也被3整除

         num num ,如果num被3整除,这个操作相当于十进制num*(2^digit(num)+1),digit()是num的二进制长度,自然也被3整除

         假设有这么一个二进制数它能被3整除并不能由这个串生成:考虑

        1)以0结尾,那么num 0将是生成这个串的一个方法,只需要向下考虑num是否能被表示,故0结尾的问题不用分析

        2)以1结尾,经过对余数的分析发现,并不能表示所有的被三整除数,如 10101 (21)就无法生成

2.2.6 不懂罗马数字。。。。


2.3.1 expr->'-' || expr1 || term | '+' || expr2 || term | term

         term->'*' || term1 || factor | '/' || term2 || factor | factor

         factor->digit | (expr)


         9-5+2    +-952

         


          9-5*2     -9*52

          


2.3.2  expr-> expr1 || '-' || term | expr2 || '+' ||  term | term

         term-> term1 || '*' || factor |  term2 || '/' || factor | factor

         factor->digit | (expr)

         


            

2.3.3 对罗马数字一窍不通

2.3.4 同上

2.3.5 expr-> {print('-')} expr1  term - | {print('+')} expr2  term + | term

         term->{print('*')} term1 factor * | {print('/')} term2 factor / | factor

         factor->{print(digit)} digit  | (expr) 


2.4.1 

1) stmt-> '+' || stmt1 || stmt2 | '-' || stmt3 || stmt4 | a

void stmt(){
    switch(lookahead){
         case '+': match('+');stmt();stmt();break;
         case '-': match('-');stmt();stmt();break;
         case 'a': match('a');break;
         default: report('syntax error');
    }
}

match(terminal t){
    if(lookahead==t) lookahead=nextTerminal;
    else report('syntax error');
}

2) stmt -> stmt1 || '(' || stmt2 || ')' || stmt3 | ε

void stmt(){
    switch(lookahead){
         case '(': match('(');stmt();match(')');break;
         case ')':break;
         default: report('syntax error');
    }
}

match(terminal t){
    if(lookahead==t) lookahead=nextTerminal;
    else report('syntax error');
}

3)stmt ->'0' || stmt1 || '1' | '01'

void stmt(){
    switch(lookahead){
         case '0': match('0');stmt();match('1');break;
         case '1':break;
         default: report('syntax error');
    }
}

match(terminal t){
    if(lookahead==t) lookahead=nextTerminal;
    else report('syntax error');
}

2.6

package afterExpression;


import java.io.IOException;
import java.util.Hashtable;


public class Lexer {
	private int peek = ' ';
	private int line = 1;
	private Hashtable<String, Word> reverseWord = new Hashtable<>();


	public Lexer() {
		reserve(new Word(Tag.TRUE, "true"));
		reserve(new Word(Tag.FALSE, "false"));
	}


	private void reserve(Word word) {
		reverseWord.put(word.getExpression(), word);
	}


	public Token scan() throws IOException {
		// 跳过空白符,换行符,记录行号
		for (;; peek = System.in.read()) {
			if (peek == ' ' || peek == '\t') {
				continue;
			} else if (peek == '\n') {
				line += 1;
				continue;
			} else {
				break;
			}
		}
		// 处理注释
		if (peek == '/') {
			peek = System.in.read();
			if (peek == '/') {
				// 行级注释
				while (peek != '\n') {
					peek = System.in.read();
				}
				peek = ' ';
				return scan();
			}
			if (peek == '*') {
				// 层级注释
				while (true) {
					peek = System.in.read();
					if (peek == '*') {
						peek = System.in.read();
						if (peek == '/') {
							peek = ' ';
							return scan();
						}
					}
				}
			}
			return new Token('/');
		}
		// 处理<= < == != >= >
		if (peek == '<' || peek == '=' || peek == '!' || peek == '>') {
			StringBuffer sb = new StringBuffer();
			sb.append((char) peek);
			peek = System.in.read();
			if (peek != '=') {
				return new Operator(Tag.RELATION, sb.toString());
			} else {
				peek = ' ';
				sb.append('=');
				return new Operator(Tag.RELATION, sb.toString());
			}
		}
		// 处理数字
		if (Character.isDigit(peek)) {
			int num = 0;
			// 向后读每次*10+新读数
			do {
				num = 10 * num + Character.digit(peek, 10);
				peek = System.in.read();
			} while (Character.isDigit(peek));
			if (peek == '.') {
				double floatnum = num;
				peek = System.in.read();
				int digitNum = 1;
				while (Character.isDigit(peek)) {
					floatnum = floatnum + Character.digit(peek, 10)
							* Math.pow(0.1, digitNum);
					peek = System.in.read();
					digitNum++;
				};
				return new FloatNum(floatnum);
			}
			return new Num(num);
		}
		if(peek=='.'){
			peek = System.in.read();
			if(Character.isDigit(peek)){
				double floatnum=0;
				int digitNum = 1;
				while (Character.isDigit(peek)) {
					floatnum = floatnum + Character.digit(peek, 10)
							* Math.pow(0.1, digitNum);
					peek = System.in.read();
					digitNum++;
				};
				return new FloatNum(floatnum);
			}else{
				return new Token('.');
			}
			
		}
		// 处理保留字和标识符
		if (Character.isLetter(peek)) {
			// 缓冲字符
			StringBuffer sb = new StringBuffer();
			do {
				sb.append((char) peek);
				peek = System.in.read();
			} while (Character.isLetter(peek));
			String s = sb.toString();
			// 如果已经在保留字表中,则返回,否则创建新的Word对象
			Word word = reverseWord.get(s);
			if (word != null) {
				return word;
			}
			word = new Word(Tag.ID, s);
			// 存入新的标识符
			reverseWord.put(s, word);
			return word;
		}
		Token t = new Token(peek);
		peek = ' ';
		return t;
	}


	public static void main(String[] args) throws IOException {
		Lexer l = new Lexer();
		while (true) {
			Token scan = l.scan();
			if (scan instanceof Num) {
				System.out.println("num:" + ((Num) scan).getValue());
			} else if (scan instanceof Word) {
				System.out.println("word:" + ((Word) scan).getExpression());
			} else if (scan instanceof Operator) {
				System.out.println("operator:"
						+ ((Operator) scan).getOperator());
			}else if (scan instanceof FloatNum) {
				System.out.println("float:"
						+ ((FloatNum) scan).getValue());
			} else {
				System.out.println("tag:" + (char) scan.getTag());
			}
		}
	}
}


package afterExpression;

public class FloatNum extends Token{
	private final double value;

	public FloatNum(double value) {
		super(Tag.FLOAT_NUM);
		this.value=value;
	}

	public double getValue() {
		return value;
	}

}


package afterExpression;

public class Operator extends Token{
	private final String operator;

	public Operator(int t,String operator) {
		super(t);
		this.operator=operator;
	}

	public String getOperator() {
		return operator;
	}

}


2.8.1

class For extends Stmt{
	Expr expr1;
	Expr expr2;
	Expr expr3;
	Stmt stmt;
	While w;
	public For(Expr expr1,Expr expr2,Expr expr3,Stmt stmt){
		this.expr1=expr1;
		this.expr2=expr2;
		this.expr3=expr3;
		this.stmt=stmt;
		Stmt stmts=new Seq(stmt,expr3);
		w=new While(expr2,stmts);
	}
	public void gen(){
		Expr n=expr1.rvalue();
		w.gen();	
	}
}
2.8.2 可以用0和1表示哟。。


猜你喜欢

转载自blog.csdn.net/zkANewer/article/details/80893588
今日推荐