灭火器说明书100字:Python:160行代码写一个编辑器和解释器 - Python编程 - ItEye新闻

来源:百度文库 编辑:偶看新闻 时间:2024/04/19 19:07:34
Python:160行代码写一个编辑器和解释器2008-06-23 14:58 by 副主编 QQbyte
评论(7) 有5421人浏览 python < = hunters.length - 1 ? hunter_id = 0 : hunter_id++; $('hunters').update(hunters[hunter_id]);return false;" href="http://www.iteye.com/news/2677#">> 猎头职位: 北京: JavaEye招聘Ruby工程师 M. Taylor写道:我在几周前开始学习Python,作为一个学习用的项目,我给自己设定的目标是编写一个简单的while语句的编辑器和解释器。写Python代码如同梦幻,工作流程如下:思考你如何解决这个问题,尝试用最高级别eval loop去解决,如果不能完成,找另外的途径,如果可行,把它放入你的模块。终于我成功了!

我用最简单的方式来写python:

Python代码
  1. stmtlist   := (statement)*   
  2. statement  :=    'if' condition stmtlist ['else' stmtlist] 'endif'  
  3.                | 'while' condition stmtlist 'endwhile'  
  4.                | label '=' expression   
  5.                | 'print' expression   
  6. condition  := expression ('=='|'!=') expression   
  7. expression := term ('+'|'-' term)*   
  8. term       := label|digit  


下面是全部代码:

Python代码
  1. #****************** Lexer ************************   
  2.   
  3. tokenlist = []   
  4. currtoken = ("", "", 0)   
  5. keywords = set(["while""endwhile""if""else""endif""print""=""==""!=""+""-"])   
  6. symboltable = dict()   
  7.   
  8. def nextToken():   
  9.     global currtoken, symboltable   
  10.     if(len(tokenlist) > 0):   
  11.         s = tokenlist.pop(0)   
  12.         if s in keywords:   
  13.             currtoken = (s, "", 0)   
  14.         elif s.isdigit():   
  15.             currtoken = ("digit", "", int(s))   
  16.         elif s.isalnum():   
  17.             symboltable[s] = 0  
  18.             currtoken = ("label", s, 0)   
  19.         else:   
  20.             print "syntax error: " + s   
  21.     else:   
  22.         currtoken = ("", "", 0)   
  23.   
  24. def consume(expected):   
  25.     if currtoken[0] == expected:   
  26.         nextToken()   
  27.     else:   
  28.         print "expected " + expected + " not found"    
  29.   
  30. #****************** Parser ************************   
  31.   
  32. def parseFile(filename):   
  33.     inputfile = open(filename, "r")   
  34.     inputstring = inputfile.read()   
  35.     global tokenlist   
  36.     tokenlist = inputstring.split()   
  37.     nextToken()   
  38.     return doStatementList()   
  39.   
  40. def doStatementList():   
  41.     stmts = []   
  42.     newstmt = []       
  43.     while currtoken[0] in ["while""if""print""label"]:   
  44.         if currtoken[0] == "while":   
  45.             # ["while", [condition], [statementlist]]   
  46.             consume("while")   
  47.             newstmt = ["while"]   
  48.             newstmt.append(doCondition())   
  49.             newstmt.append(doStatementList())   
  50.             consume("endwhile")   
  51.         elif currtoken[0] == "if":   
  52.             # ["if", [condition], [then part], [else part]]   
  53.             consume("if")   
  54.             newstmt = ["if"]   
  55.             newstmt.append(doCondition())   
  56.             newstmt.append(doStatementList())   
  57.             if currtoken[0] == "else":   
  58.                 consume("else")   
  59.                 newstmt.append(doStatementList())   
  60.             consume("endif")   
  61.         elif currtoken[0] == "print":   
  62.             # ["print", [expression]]   
  63.             consume("print")   
  64.             newstmt = ["print"]   
  65.             newstmt.append(doExpression())   
  66.         elif currtoken[0] == "label":   
  67.             # ["=", [expression], [expression]]   
  68.             label = [currtoken[1]]   
  69.             nextToken()   
  70.             consume("=")   
  71.             newstmt = ["="]   
  72.             newstmt.append(label)   
  73.             newstmt.append(doExpression())   
  74.         else:   
  75.             print "invalid statement: " + currtoken[0]   
  76.         stmts.append(newstmt)   
  77.     return stmts   
  78.   
  79. def doCondition():   
  80.     exp = doExpression()   
  81.     # ["==|!=", [left side], [right side]]   
  82.     if currtoken[0] in ["==""!="]:   
  83.         retval = [currtoken[0]]   
  84.         retval.append(exp)   
  85.         nextToken()   
  86.         retval.append(doExpression())   
  87.     else:   
  88.         print "expected == or != not found"  
  89.     return retval   
  90.        
  91. def doExpression():   
  92.     term = doTerm()   
  93.     # carry the term in case there's no +|-   
  94.     exp = term   
  95.     # ["+|-", [left side], [right side]]   
  96.     while currtoken[0] in ["+""-"]:   
  97.         exp = [currtoken[0]]   
  98.         nextToken()   
  99.         exp.append(term)   
  100.         exp.append(doExpression())   
  101.     return exp   
  102.   
  103. def doTerm():   
  104.     if currtoken[0] == "label":   
  105.         retval = currtoken[1]   
  106.         nextToken()   
  107.     elif currtoken[0] == "digit":   
  108.         retval = currtoken[2]   
  109.         nextToken()   
  110.     return [retval]   
  111.   
  112. #****************** Interpreter ************************   
  113. stack = []   
  114. def execStatementList(pgm):   
  115.     for stmt in pgm:   
  116.         execStatement(stmt)   
  117.            
  118. def execStatement(stmt):   
  119.     if stmt[0] == "while":   
  120.         execCondition(stmt[1])   
  121.         while stack.pop():   
  122.             execStatementList(stmt[2])   
  123.             execCondition(stmt[1])   
  124.     elif stmt[0] == "if":   
  125.         execCondition(stmt[1])   
  126.         if stack.pop():   
  127.             execStatementList(stmt[2])   
  128.         elif len(stmt) == 4:   
  129.             execStatementList(stmt[3])   
  130.     elif stmt[0] == "=":   
  131.         execExpression(stmt[2])   
  132.         symboltable[stmt[1][0]] = stack.pop()   
  133.     elif stmt[0] == "print":   
  134.         execExpression(stmt[1])   
  135.         print "output:" + str(stack.pop())   
  136.     else:   
  137.         print "invalid statement"  
  138.        
  139. def execCondition(cond):   
  140.     execExpression(cond[1])   
  141.     execExpression(cond[2])   
  142.     if cond[0] == "==":   
  143.         stack.append(stack.pop() == stack.pop())   
  144.     elif cond[0] == "!=":   
  145.         stack.append(stack.pop() != stack.pop())   
  146.   
  147. def execExpression(exp):   
  148.     if len(exp) == 3:   
  149.         execExpression(exp[1])   
  150.         execExpression(exp[2])   
  151.         if exp[0] == "+":   
  152.             stack.append(stack.pop() + stack.pop())   
  153.         else:   
  154.             stack.append(stack.pop() - stack.pop())   
  155.     else:   
  156.         if type(exp[0]) == int:   
  157.             stack.append(exp[0])   
  158.         else:   
  159.             stack.append(symboltable[exp[0]])