Advertisement
Guest User

Untitled

a guest
Feb 20th, 2017
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.06 KB | None | 0 0
  1. """
  2. Author: Rudy Bermudez
  3. Filename: parser.py
  4. Assignment: HW3
  5. Description: Controls Parsing Tasks
  6. """
  7.  
  8. import mytoken
  9. from error import Error
  10. from mypl_ast import *
  11.  
  12.  
  13. class Parser(object):
  14.  
  15.     def __init__(self, lexer):
  16.         """ Initializes the Parser Class
  17.        :param lexer: Instance of `Lexer`
  18.        """
  19.         self.lexer = lexer
  20.         self.current_token = None
  21.  
  22.     def parse(self):
  23.         """ Starts the reverse descent parser
  24.  
  25.        Succeeds if program is syntactically well-formed
  26.        """
  27.         stmt_list_node = StmtList()
  28.         self.__advance()
  29.         self.__stmts(stmt_list_node)
  30.         self.__expect(mytoken.EOS, 'expecting end of file')
  31.         return stmt_list_node
  32.  
  33.     def __advance(self):
  34.         """ Calls for the next token from the `lexer` and stores it to `self.current_token` """
  35.         self.current_token = self.lexer.next_token()
  36.  
  37.     def __expect(self, tokentype, error_msg):
  38.         """ Checks to see if the current token is what is syntactically expected
  39.        :param tokentype: the expected token type of type `Token`
  40.        :param error_msg: the error message to be delivered to the console
  41.        """
  42.         if self.current_token.tokentype == tokentype:
  43.             self.__advance()
  44.         else:
  45.             self.__error(error_msg)
  46.  
  47.     def __error(self, error_msg):
  48.         """ Raises an Error
  49.        :param error_msg: the error message to be delivered to the console
  50.        """
  51.         s = error_msg + ' found "' + self.current_token.lexeme + '"'
  52.         l = self.current_token.line
  53.         c = self.current_token.column
  54.         raise Error(s, l, c)
  55.  
  56.     def __stmts(self, stmt_list_node):
  57.         if not (self.current_token.tokentype == mytoken.EOS
  58.                 or self.current_token.tokentype == mytoken.END
  59.                 or self.current_token.tokentype == mytoken.ELSE
  60.                 or self.current_token.tokentype == mytoken.ELSEIF
  61.                 ):
  62.             self.__stmt(stmt_list_node)
  63.             self.__stmts(stmt_list_node)
  64.  
  65.     def __stmt(self, stmt_list_node):
  66.         if self.current_token.tokentype == mytoken.PRINT or self.current_token.tokentype == mytoken.PRINTLN:
  67.             self.__output(stmt_list_node)
  68.         elif self.current_token.tokentype == mytoken.ID:
  69.             self.__assign(stmt_list_node)
  70.         elif self.current_token.tokentype == mytoken.IF:
  71.             self.__cond(stmt_list_node)
  72.         elif self.current_token.tokentype == mytoken.WHILE:
  73.             self.__loop(stmt_list_node)
  74.  
  75.     # Done
  76.     def __output(self, stmt_list_node):
  77.         print_node = PrintStmt()
  78.         if self.current_token.tokentype == mytoken.PRINT:
  79.             print_node.is_println = False
  80.             self.__advance()
  81.             self.__expect(mytoken.LPAREN, 'expecting "("')
  82.             print_node.expr = self.__expr()
  83.             self.__expect(mytoken.RPAREN, 'expecting ")"')
  84.             self.__expect(mytoken.SEMICOLON, 'expecting ";"')
  85.             stmt_list_node.stmts.append(print_node)
  86.  
  87.         elif self.current_token.tokentype == mytoken.PRINTLN:
  88.             print_node.is_println = True
  89.             self.__advance()
  90.             self.__expect(mytoken.LPAREN, 'expecting "("')
  91.             print_node.expr = self.__expr()
  92.             self.__expect(mytoken.RPAREN, 'expecting ")"')
  93.             self.__expect(mytoken.SEMICOLON, 'expecting ";"')
  94.             stmt_list_node.stmts.append(print_node)
  95.  
  96.     def __input(self):
  97.         # Should this function return?
  98.         read_node = ReadExpr()
  99.         if self.current_token.tokentype == mytoken.READINT:
  100.             read_node.is_read_int = True
  101.             self.__advance()
  102.             self.__expect(mytoken.LPAREN, 'expecting "("')
  103.             read_node.msg = self.current_token
  104.             self.__expect(mytoken.STRING, 'expecting "STRING"')
  105.             self.__expect(mytoken.RPAREN, 'expecting ")"')
  106.             self.__value()
  107.             return read_node
  108.  
  109.         elif self.current_token.tokentype == mytoken.READSTR:
  110.             self.__advance()
  111.             read_node.is_read_int = False
  112.             self.__expect(mytoken.LPAREN, 'expecting "("')
  113.             read_node.msg = self.current_token
  114.             self.__expect(mytoken.STRING, 'expecting "STRING"')
  115.             self.__expect(mytoken.RPAREN, 'expecting ")"')
  116.             self.__value()
  117.             return read_node
  118.  
  119.     # Done
  120.     def __assign(self, stmt_list_node):
  121.         assign_node = AssignStmt()
  122.         assign_node.lhs = self.current_token
  123.         self.__advance()
  124.         assign_node.index_expr = self.__listindex()
  125.         self.__expect(mytoken.ASSIGN, 'expecting "="')
  126.         assign_node.rhs = self.__expr()
  127.         self.__expect(mytoken.SEMICOLON, 'expecting ";"')
  128.         stmt_list_node.stmts.append(assign_node)
  129.  
  130.     # Done
  131.     def __listindex(self):
  132.         index_expr = IndexExpr()
  133.         if self.current_token.tokentype == mytoken.LBRACKET:
  134.             self.__advance()
  135.             index_expr.identifier = self.current_token
  136.             index_expr.expr = self.__expr()
  137.             self.__expect(mytoken.RBRACKET, 'expecting "]"')
  138.             return index_expr
  139.  
  140.     def __expr(self):
  141.         expr_list = ListExpr()
  142.         # TODO: Rudy - Do I pass in expr_list to value() and exprt()?
  143.         self.__value(expr_list)
  144.         self.__exprt(expr_list)
  145.         return expr_list
  146.  
  147.     def __value(self, expr_list):
  148.         # Should this method return or append?
  149.         if self.current_token.tokentype == mytoken.ID:
  150.             simple_expr_node = SimpleExpr()
  151.             simple_expr_node.term = self.current_token
  152.             self.__advance()
  153.             self.__listindex()  # What do I do with this list index?
  154.             expr_list.expressions.append(simple_expr_node)
  155.         elif (self.current_token.tokentype == mytoken.STRING
  156.               or self.current_token.tokentype == mytoken.INT
  157.               or self.current_token.tokentype == mytoken.BOOL
  158.               ):
  159.             simple_expr_node = SimpleExpr()
  160.             simple_expr_node.term = self.current_token
  161.             self.__advance()
  162.             expr_list.expressions.append(simple_expr_node)
  163.         elif self.current_token.tokentype == mytoken.LBRACKET:
  164.             # TODO: Rudy - What do I do in this case?
  165.             self.__advance()
  166.             self.__exprlist()
  167.             self.__expect(mytoken.RBRACKET, 'expecting "]"')
  168.         else:
  169.             expr_list.expressions.append(self.__input())
  170.  
  171.     def __exprt(self, expr_list):
  172.         if (self.current_token.tokentype == mytoken.PLUS
  173.             or self.current_token.tokentype == mytoken.MINUS
  174.             or self.current_token.tokentype == mytoken.DIVIDE
  175.             or self.current_token.tokentype == mytoken.MULTIPLY
  176.             or self.current_token.tokentype == mytoken.MODULUS
  177.             ):
  178.             self.__math_rel()
  179.             self.__expr()
  180.  
  181.     def __exprlist(self):
  182.         # TODO: Do I have to do a nested check of <expr> and <value> ?
  183.         self.__expr()
  184.         self.__exprtail()
  185.  
  186.     def __exprtail(self):
  187.         if self.current_token.tokentype == mytoken.COMMA:
  188.             self.__advance()
  189.             self.__expr()
  190.             self.__exprtail()
  191.  
  192.     def __math_rel(self):
  193.         self.__advance()
  194.  
  195.     def __cond(self):
  196.         self.__advance()
  197.         self.__bexpr()
  198.         self.__expect(mytoken.THEN, 'expecting "THEN"')
  199.         self.__stmts()
  200.         self.__condt()
  201.         self.__expect(mytoken.END, 'expecting "END"')
  202.  
  203.     def __condt(self):
  204.         if self.current_token.tokentype == mytoken.ELSEIF:
  205.             self.__advance()
  206.             self.__bexpr()
  207.             self.__expect(mytoken.THEN, 'expecting "THEN"')
  208.             self.__stmts()
  209.             self.__condt()
  210.         elif self.current_token.tokentype == mytoken.ELSE:
  211.             self.__advance()
  212.             self.__stmts()
  213.  
  214.     def __bexpr(self):
  215.         if self.current_token.tokentype == mytoken.NOT:
  216.             self.__advance()
  217.             self.__expr()
  218.             self.__bexprt()
  219.         else:
  220.             self.__expr()
  221.             self.__bexprt()
  222.  
  223.     def __bexprt(self):
  224.         if (self.current_token.tokentype == mytoken.EQUAL
  225.             or self.current_token.tokentype == mytoken.LESS_THAN
  226.             or self.current_token.tokentype == mytoken.GREATER_THAN
  227.             or self.current_token.tokentype == mytoken.LESS_THAN_EQUAL
  228.             or self.current_token.tokentype == mytoken.GREATER_THAN_EQUAL
  229.             or self.current_token.tokentype == mytoken.NOT_EQUAL
  230.             ):
  231.             self.__bool_rel()
  232.             self.__expr()
  233.             self.__bconnect()
  234.  
  235.     def __bconnect(self):
  236.         if self.current_token.tokentype == mytoken.AND:
  237.             self.__advance()
  238.             self.__bexpr()
  239.         elif self.current_token.tokentype == mytoken.OR:
  240.             self.__advance()
  241.             self.__bexpr()
  242.  
  243.     def __bool_rel(self):
  244.         self.__advance()
  245.  
  246.     def __loop(self):
  247.         self.__advance()
  248.         self.__bexpr()
  249.         self.__expect(mytoken.DO, 'expecting "DO"')
  250.         self.__stmts()
  251.         self.__expect(mytoken.END, 'expecting "END"')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement