让我们搞个编译器,第二章的python实现


# 编译一位数四则运算
# 原教材 第二篇。
# 
# 若改为x86,则需要调整输出语句。同时R0可设为eax,R1设为edx。
# x86 也差不多式微了,苹果都抛弃了它。不知说什么好。
#--------------------------------------------------------------
"""program Cradle"""

#--------------------------------------------------------------
# Constant Declarations 

TAB = '    ● '
src="1+2*4+5-6*(1+2)/((-3+4)+(5-6))" # 源代码脚本
#src='1-2'
print(src+"\n")
#___________________________
class source():
    def __init__(self,f):
        self.file=f
        self.step=0
        self.size=len(f)
    def read(self):
        if self.step < self.size:
            rt=self.file[self.step]
            self.step+=1
            print(rt)
            return rt
        else:
            return None
src=source(src)
#--------------------------------------------------------------
# Variable Declarations 

Look=""  # char              # Lookahead Character 
                              
#--------------------------------------------------------------
# Read New Character From Input Stream 

def  GetChar():
   global Look
   Look=src.read()

#--------------------------------------------------------------
# Report an Error 

def  Error(s: str):

   WriteLn=print
   WriteLn('Error: ', s, '.')

#--------------------------------------------------------------
# Report Error and Halt 

def  Abort(s: str):

   Error(s)
   quit()

#--------------------------------------------------------------
# Report What Was Expected 

def  Expected(s: str):

   Abort(s + ' Expected')

#--------------------------------------------------------------
# Match a Specific Input Character 

def  Match(x: chr):

   if Look == x :
     GetChar ()
   else: Expected('☞ ' + x + ' ')

#--------------------------------------------------------------
# Recognize an Alpha Character 

def IsAlpha(c: chr): #boolean

   return c.isalpha()

#--------------------------------------------------------------

# Recognize a Decimal Digit 

def  IsDigit(c: chr): # boolean

     return c.isdigit()

#--------------------------------------------------------------
# Get an Identifier 

def  GetName(): #char

   if not IsAlpha(Look) :
       Expected('Name')
   rt= Look.upper()
   GetChar()
   return rt

#--------------------------------------------------------------
# Get a Number 

def  GetNum(): #char

   if not IsDigit(Look) :
       Expected('Integer')
   rt = Look
   GetChar()
   return rt

#--------------------------------------------------------------
# Output a String with Tab 

def  Emit(s: str):
   Write=print
   Write(TAB, s)

#--------------------------------------------------------------
# Output a String with Tab and CRLF 

def  EmitLn(s: str):

   Emit(s)
   WriteLn=print
   WriteLn()


#--------------------------------------------------------------
# Initialize 

def  Init():

   GetChar()

#------------------------------------------------------
#def  Expression(): # 2.1
#def Term(): # 2.2
#------------------------------------------------------
def  Factor():
   global Look
   if Look == '(' :
      Match ('(')
      Expression()
      Match(')' )
   else:
      EmitLn('#' + GetNum() + ' --> R0')

#--------------------------------------------------------------
def IsAddop(c: chr): # boolean
     return  c in ['+', '-']
     
def  Expression(): # 2  expression ::= term [op term]*
    global Look
    if IsAddop(Look) : 
      EmitLn('CLR D0')
    else:
      Term()
    while Look in ['+', '-'] : 
      EmitLn('R0 --> PUSH')

      if Look =='+': Add()
      elif Look == '-': Subtract()
      else: Expected('加法操作符')
#--------------------------------------------------------------

def  Add():

   Match('+')
   Term()
   #EmitLn('ADD D1,D0')
  
   EmitLn ("POP  --> R1" )     #('ADD (SP)+,R0')
   EmitLn ('ADD R1, R0 --> R0')
   # x86
   #       ADD R0, R1 --> R0
   
#--------------------------------------------------------------
def  Subtract():

   Match('-')
   Term()
   EmitLn('POP -->R1')  # ('SUB (SP)+,R0')
   EmitLn('SUB R1, R0 --> R0 ')
   EmitLn('NEG R0')
   #  x86
   #         SUB    R1, R0  --> R1
   #         MOV  R0 , R1 --> R0

#--------------------------------------------------------------
# Recognize and Translate a Multiply 

def  Multiply():

    Match('*')
    Factor()
    EmitLn("POP --> R1")         # ('MULS (SP)+,R0')
    EmitLn("MULS R1, R0  --> R0")         
    # x86 
    #        MUL R0,R1 --> R0
#--------------------------------------------------------------
def  Divide():

    Match('/')
    Factor()
    EmitLn('POP  --> R1')
    EmitLn('DIVS R1, R0 --> R0')
    # x86
    #      DIV  R1, R0 --> R1
    #      MOV  R0, R1 --> R0
#--------------------------------------------------------------
def  Term():
    global Look
    Factor()
    while Look in ['*', '/'] :
       EmitLn('R0 --> PUSH')
      
       if Look == '*': Multiply()
       elif Look == '/': Divide()
       else: Expected('Mulop')
#--------------------------------------------------------------      
Init()
Expression()

上一篇:如何用一个语句判断一个整数是不是二的整数次幂——从一道简单的面试题浅谈C语言的类型提升(type promotion)


下一篇:(Mathtype)LaTeX风格公式样式