예제 #1
0
def B(token_generator):
    token, token_id = token_generator.send(True)
    # func_is_read = match(token, token_id, table.READ)
    if match(token, token_id, table.READ) or match(token, token_id,
                                                   table.WRITE):
        # 成功,冲刷
        next(token_generator)
        token, token_id = next(token_generator)
        if not match(token, token_id, table.LEFT_BRACKET):
            err('In Line %d    B : can not match (' % line_no)
        D(token_generator)
        if not is_var_exist(current_token, current_proc, 0, True):
            err('In Line %d    B : can not find token %s' %
                (line_no, current_token))
        # if func_is_read:
        # add_var(current_token, current_proc, 0, 'integer', plevel)

        token, token_id = next(token_generator)
        if not match(token, token_id, table.RIGHT_BRACKET):
            err('In Line %d    B : can not match )' % line_no)
    elif match(token, token_id, table.IF):
        # 成功,冲刷
        next(token_generator)
        U(token_generator)
        token, token_id = next(token_generator)
        if not match(token, token_id, table.THEN):
            err('In Line %d    B : can not match then' % line_no)
        B(token_generator)
        token, token_id = next(token_generator)
        if not match(token, token_id, table.ELSE):
            err('In Line %d    B : can not match else' % line_no)
        B(token_generator)
    else:
        Z(token_generator)
예제 #2
0
파일: parser.py 프로젝트: ay27/compiler
def S(token_generator, pname, ptype):
    global plevel, current_proc
    plevel += 1
    # 注意到函数有且仅有一个参数,而刚进入函数体时,变量表中的最后一个必为此参数
    if len(var_table) == 0:
        current_proc = Proc(pname, ptype, plevel)
    else:
        current_proc = Proc(pname, ptype, plevel)
        var_table[len(var_table) - 1].vproc = current_proc
    proc_table.append(current_proc)
    # 同时,由于在函数内可以直接把自身函数名当成一个变量来使用,所以需要把函数名加入到变量表
    add_var(pname, current_proc, 0, 'integer', plevel)

    token, token_id = next(token_generator)
    if not match(token, token_id, table.BEGIN):
        err('In line %d    S : Not start with begin' % line_no)
    H(token_generator)
    # token, token_id = next(token_generator)
    # if not match(token, token_id, table.SEMICOLON):
    # err('S : A ; must follow H')
    E(token_generator)
    token, token_id = next(token_generator)
    if not match(token, token_id, table.END):
        err('In Line %d    S : there must be an \'end\'' % line_no)

    plevel -= 1
    current_proc = proc_table[plevel - 1]
    return
예제 #3
0
파일: parser.py 프로젝트: ay27/compiler
def B(token_generator):
    token, token_id = token_generator.send(True)
    # func_is_read = match(token, token_id, table.READ)
    if match(token, token_id, table.READ) or match(token, token_id, table.WRITE):
        # 成功,冲刷
        next(token_generator)
        token, token_id = next(token_generator)
        if not match(token, token_id, table.LEFT_BRACKET):
            err('In Line %d    B : can not match (' % line_no)
        D(token_generator)
        if not is_var_exist(current_token, current_proc, 0, True):
            err('In Line %d    B : can not find token %s' % (line_no, current_token))
        # if func_is_read:
        # add_var(current_token, current_proc, 0, 'integer', plevel)

        token, token_id = next(token_generator)
        if not match(token, token_id, table.RIGHT_BRACKET):
            err('In Line %d    B : can not match )' % line_no)
    elif match(token, token_id, table.IF):
        # 成功,冲刷
        next(token_generator)
        U(token_generator)
        token, token_id = next(token_generator)
        if not match(token, token_id, table.THEN):
            err('In Line %d    B : can not match then' % line_no)
        B(token_generator)
        token, token_id = next(token_generator)
        if not match(token, token_id, table.ELSE):
            err('In Line %d    B : can not match else' % line_no)
        B(token_generator)
    else:
        Z(token_generator)
예제 #4
0
def S(token_generator, pname, ptype):
    global plevel, current_proc
    plevel += 1
    # 注意到函数有且仅有一个参数,而刚进入函数体时,变量表中的最后一个必为此参数
    if len(var_table) == 0:
        current_proc = Proc(pname, ptype, plevel)
    else:
        current_proc = Proc(pname, ptype, plevel)
        var_table[len(var_table) - 1].vproc = current_proc
    proc_table.append(current_proc)
    # 同时,由于在函数内可以直接把自身函数名当成一个变量来使用,所以需要把函数名加入到变量表
    add_var(pname, current_proc, 0, 'integer', plevel)

    token, token_id = next(token_generator)
    if not match(token, token_id, table.BEGIN):
        err('In line %d    S : Not start with begin' % line_no)
    H(token_generator)
    # token, token_id = next(token_generator)
    # if not match(token, token_id, table.SEMICOLON):
    # err('S : A ; must follow H')
    E(token_generator)
    token, token_id = next(token_generator)
    if not match(token, token_id, table.END):
        err('In Line %d    S : there must be an \'end\'' % line_no)

    plevel -= 1
    current_proc = proc_table[plevel - 1]
    return
예제 #5
0
파일: parser.py 프로젝트: ay27/compiler
def Z(token_generator):
    D(token_generator)
    if not is_var_exist(current_token, current_proc, 0, True):
        err('In Line %d     Z : token %s not defined' % (line_no, current_token))
    token, token_id = next(token_generator)
    if not match(token, token_id, table.ASSIGN):
        err('In Line %d    Z : can not match := %s' % (line_no, token))
    K(token_generator)
예제 #6
0
def Z(token_generator):
    D(token_generator)
    if not is_var_exist(current_token, current_proc, 0, True):
        err('In Line %d     Z : token %s not defined' % (line_no, current_token))
    token, token_id = next(token_generator)
    if not match(token, token_id, table.ASSIGN):
        err('In Line %d    Z : can not match := %s' % (line_no, token))
    K(token_generator)
예제 #7
0
파일: parser.py 프로젝트: ay27/compiler
def H(token_generator):
    token, token_id = next(token_generator)
    if not match(token, token_id, table.INTEGER):
        err('In Line %d   H : can not match integer' % line_no)
    V(token_generator)
    token, token_id = next(token_generator)
    if not match(token, token_id, table.SEMICOLON):
        err('In Line %d   H : can not match ;' % line_no)
    _H(token_generator)
    return
예제 #8
0
def H(token_generator):
    token, token_id = next(token_generator)
    if not match(token, token_id, table.INTEGER):
        err('In Line %d   H : can not match integer' % line_no)
    V(token_generator)
    token, token_id = next(token_generator)
    if not match(token, token_id, table.SEMICOLON):
        err('In Line %d   H : can not match ;' % line_no)
    _H(token_generator)
    return
예제 #9
0
def _H(token_generator):
    token, token_id = token_generator.send(True)
    # 没有匹配成功,可能是e,需要回退一步
    if not match(token, token_id, table.INTEGER):
        return
    # 匹配integer成功,需要把重复的这个yield冲刷掉
    next(token_generator)
    V(token_generator)
    token, token_id = next(token_generator)
    if not match(token, token_id, table.SEMICOLON):
        err('In Line %d    H : can not match ;' % line_no)
    _H(token_generator)
예제 #10
0
파일: parser.py 프로젝트: ay27/compiler
def _H(token_generator):
    token, token_id = token_generator.send(True)
    # 没有匹配成功,可能是e,需要回退一步
    if not match(token, token_id, table.INTEGER):
        return
    # 匹配integer成功,需要把重复的这个yield冲刷掉
    next(token_generator)
    V(token_generator)
    token, token_id = next(token_generator)
    if not match(token, token_id, table.SEMICOLON):
        err('In Line %d    H : can not match ;' % line_no)
    _H(token_generator)
예제 #11
0
파일: parser.py 프로젝트: ay27/compiler
def add_var(token, proc, kind, type, vlev):
    """
        只有两个地方会引入新变量:
            1. 变量定义和函数定义 V
            2. read   B
    :param token:
    :param proc:
    :param kind: 分类vkind: 0..1(0—变量、1—形参)
    :param type:
    :param vlev:
    :return:
    """
    if is_var_exist(token, proc=proc, kind=kind, expected=False):
        err('In line %d    AddVar : can not define a variable in twice' % line_no)
    var_table.append(Variable(token, proc, kind, type, vlev, len(var_table)))
    for i in range(0, proc.plev):
        if proc_table[i].plev < vlev or (proc_table[i].plev == vlev and proc_table[i].adr == proc.adr):
            proc_table[i].ladr += 1
예제 #12
0
def add_var(token, proc, kind, type, vlev):
    """
        只有两个地方会引入新变量:
            1. 变量定义和函数定义 V
            2. read   B
    :param token:
    :param proc:
    :param kind: 分类vkind: 0..1(0—变量、1—形参)
    :param type:
    :param vlev:
    :return:
    """
    if is_var_exist(token, proc=proc, kind=kind, expected=False):
        err('In line %d    AddVar : can not define a variable in twice' %
            line_no)
    var_table.append(Variable(token, proc, kind, type, vlev, len(var_table)))
    for i in range(0, proc.plev):
        if proc_table[i].plev < vlev or (proc_table[i].plev == vlev
                                         and proc_table[i].adr == proc.adr):
            proc_table[i].ladr += 1
예제 #13
0
파일: parser.py 프로젝트: ay27/compiler
def V(token_generator):
    token, token_id = token_generator.send(True)
    if not match(token, token_id, table.FUNCTION):
        D(token_generator)
        add_var(current_token, current_proc, 0, 'integer', plevel)
        return
    # 冲刷掉当前token
    next(token_generator)
    D(token_generator)
    func_name = current_token
    token, token_id = next(token_generator)
    if not match(token, token_id, table.LEFT_BRACKET):
        err('In line %d    V : can not match (' % line_no)
    M(token_generator)
    # 由于current_proc尚未生成,先赋值为当前proc,在进入函数时需要重新设置
    add_var(current_token, current_proc, 1, 'integer', plevel + 1)

    token, token_id = next(token_generator)
    if not match(token, token_id, table.RIGHT_BRACKET):
        err('In Line %d    V : can not match )' % line_no)
    token, token_id = next(token_generator)
    if not match(token, token_id, table.SEMICOLON):
        err('In Line %d    V : can not match ;' % line_no)

    S(token_generator, func_name, 'integer')
예제 #14
0
def Y(token_generator):
    # 先检查是否是数字
    if N(token_generator):
        _Q(token_generator)
        return

    # 然后检查是否是函数调用
    D(token_generator)
    func_name = current_token
    token, token_id = token_generator.send(True)
    if not match(token, token_id, table.LEFT_BRACKET):
        # 不是函数调用
        if not is_var_exist(current_token, current_proc, 0, True):
            err('In Line %d    Y : %s is not defined' %
                (line_no, current_token))
        _D(token_generator)
        return

    # 确实是函数
    # 检查函数是否已定义
    flag = False
    for proc in proc_table:
        if proc.pname == func_name:
            flag = True
            break
    if not flag:
        err('In Line %d    P : function not defined' % line_no)
    # 冲刷
    next(token_generator)
    K(token_generator)
    token, token_id = next(token_generator)
    if not match(token, token_id, table.RIGHT_BRACKET):
        err('In Line %d    P : can not match )' % line_no)
예제 #15
0
파일: parser.py 프로젝트: ay27/compiler
def Y(token_generator):
    # 先检查是否是数字
    if N(token_generator):
        _Q(token_generator)
        return

    # 然后检查是否是函数调用
    D(token_generator)
    func_name = current_token
    token, token_id = token_generator.send(True)
    if not match(token, token_id, table.LEFT_BRACKET):
        # 不是函数调用
        if not is_var_exist(current_token, current_proc, 0, True):
            err('In Line %d    Y : %s is not defined' % (line_no, current_token))
        _D(token_generator)
        return

    # 确实是函数
    # 检查函数是否已定义
    flag = False
    for proc in proc_table:
        if proc.pname == func_name:
            flag = True
            break
    if not flag:
        err('In Line %d    P : function not defined' % line_no)
    # 冲刷
    next(token_generator)
    K(token_generator)
    token, token_id = next(token_generator)
    if not match(token, token_id, table.RIGHT_BRACKET):
        err('In Line %d    P : can not match )' % line_no)
예제 #16
0
def V(token_generator):
    token, token_id = token_generator.send(True)
    if not match(token, token_id, table.FUNCTION):
        D(token_generator)
        add_var(current_token, current_proc, 0, 'integer', plevel)
        return
    # 冲刷掉当前token
    next(token_generator)
    D(token_generator)
    func_name = current_token
    token, token_id = next(token_generator)
    if not match(token, token_id, table.LEFT_BRACKET):
        err('In line %d    V : can not match (' % line_no)
    M(token_generator)
    # 由于current_proc尚未生成,先赋值为当前proc,在进入函数时需要重新设置
    add_var(current_token, current_proc, 1, 'integer', plevel + 1)

    token, token_id = next(token_generator)
    if not match(token, token_id, table.RIGHT_BRACKET):
        err('In Line %d    V : can not match )' % line_no)
    token, token_id = next(token_generator)
    if not match(token, token_id, table.SEMICOLON):
        err('In Line %d    V : can not match ;' % line_no)

    S(token_generator, func_name, 'integer')
예제 #17
0
파일: lexer.py 프로젝트: ay27/compiler
def get_next_token(src_file):
    for line in src_file:
        token = ''
        for ch in line:
            if ch == ' ' or ch == '\t' or ch == '\r' or ch == '\n':
                if token is not None and len(token) > 0:
                    out_dyd(token, parse_token(token))
                    yield token
                token = ''
            elif token == '' and ch.isdigit():
                err('must not be number start')
            # 三种情况,一个是单词结束,一个是算符结束,一个是两个算符并排,如);
            elif is_word_end(token, ch) or is_operation_end(token, ch) or \
                    (is_operation(token) and is_operation(ch) and not is_operation('%s%s' % (token, ch))):
                out_dyd(token, parse_token(token))
                yield token
                token = ch
            else:
                token += ch
        out_dyd(table.EOLN, table.TOKEN_TABLE.get(table.EOLN))
        # yield table.EOLN
    out_dyd(table.EOF, table.TOKEN_TABLE.get(table.EOF))
    debug('finish')
예제 #18
0
파일: lexer.py 프로젝트: handsome-fish/pl0
def get_next_token(src_file):
    for line in src_file:
        token = ''
        for ch in line:
            if ch == ' ' or ch == '\t' or ch == '\r' or ch == '\n':
                if token is not None and len(token) > 0:
                    out_dyd(token, parse_token(token))
                    yield token
                token = ''
            elif token == '' and ch.isdigit():
                err('must not be number start')
            # 三种情况,一个是单词结束,一个是算符结束,一个是两个算符并排,如);
            elif is_word_end(token, ch) or is_operation_end(token, ch) or \
                    (is_operation(token) and is_operation(ch) and not is_operation('%s%s' % (token, ch))):
                out_dyd(token, parse_token(token))
                yield token
                token = ch
            else:
                token += ch
        out_dyd(table.EOLN, table.TOKEN_TABLE.get(table.EOLN))
        # yield table.EOLN
    out_dyd(table.EOF, table.TOKEN_TABLE.get(table.EOF))
    debug('finish')
예제 #19
0
def S(token_generator, pname, ptype):
    global plevel, current_proc
    plevel += 1
    # 注意到函数有且仅有一个参数,而刚进入函数体时,变量表中的最后一个必为此参数
	#变量表为空,说明是程序开始
    if len(var_table) == 0:
		#初始化过程表
        current_proc = Proc(pname, ptype, plevel)
    else:
        current_proc = Proc(pname, ptype, plevel)
        var_table[len(var_table) - 1].vproc = current_proc
	#把当前过程加入到过程表中
    proc_table.append(current_proc)
    # 同时,由于在函数内可以直接把自身函数名当成一个变量来使用,所以需要把函数名加入到变量表
    add_var(pname, current_proc, 0, 'integer', plevel)
	#由迭代器获取下一行的token及其种别码
    token, token_id = next(token_generator)
	#查看token是否为begin
    if not match(token, token_id, table.BEGIN):
        err('In line %d    S : Not start with begin' % line_no)
	#H非终结符子函数
    H(token_generator)
    # token, token_id = next(token_generator)
    # if not match(token, token_id, table.SEMICOLON):
    # err('S : A ; must follow H')
	#E非终结符子函数
    E(token_generator)
	#由迭代器获取下一行的token及其种别码
    token, token_id = next(token_generator)
	#查看token是否为end
    if not match(token, token_id, table.END):
        err('In Line %d    S : there must be an \'end\'' % line_no)
	#设置当前过程
    plevel -= 1
    current_proc = proc_table[plevel - 1]
    return
예제 #20
0
from lexer import lex
from io_lib import err, debug
import g
from parser import parse

__author__ = 'ay27'

from table import init_token_table

if __name__ == '__main__':
    try:
        g.pas_src = open(g.src_file_name)
    except OSError:
        err('can not open file %s' % g.src_file_name)
        exit(-1)

    if g.pas_src is None:
        err('can not open file %s' % g.src_file_name)
        exit(-1)

    init_token_table()
    debug('token table init finish')
    try:
        lex(g.pas_src)
    except IOError:
        err('something error')
    debug('lex finish')

    g.dyd = open('test.dyd')
    try:
        parse(g.dyd)
예제 #21
0
파일: parser.py 프로젝트: ay27/compiler
def O(token_generator):
    token, token_id = next(token_generator)
    if not match(token, token_id, None):
        err('In Line %d    O : can not match %s' % (line_no, token))
예제 #22
0
파일: parser.py 프로젝트: ay27/compiler
def Q(token_generator):
    if not N(token_generator):
        err('In Line %d    Q : match number error %s' % (line_no, current_token))
    _Q(token_generator)
예제 #23
0
def D(token_generator):
    if not G(token_generator):
        err('In Line %d    D : match %s error' % (line_no, current_token))
    _D(token_generator)
    return
예제 #24
0
def Q(token_generator):
    if not N(token_generator):
        err('In Line %d    Q : match number error %s' %
            (line_no, current_token))
    _Q(token_generator)
예제 #25
0
def O(token_generator):
    token, token_id = next(token_generator)
    if not match(token, token_id, None):
        err('In Line %d    O : can not match %s' % (line_no, token))
예제 #26
0
파일: parser.py 프로젝트: ay27/compiler
def D(token_generator):
    if not G(token_generator):
        err('In Line %d    D : match %s error' % (line_no, current_token))
    _D(token_generator)
    return