Commits

Ahmed Youssef committed 5e7bf1a

parser

Comments (0)

Files changed (2)

 
 #we have no keywords
 
-tokens=('ID', 'NUMBER', 'STRING', 'COLON', 'LT', 'GT', 'GE', 'LE',  'EQ','EQUALS',
+tokens=('FUNCTION', 'ID', 'NUMBER', 'STRING', 'COLON', 'LT', 'GT', 'GE', 'LE',  'EQ','EQUALS',
          'PLUS', 'NE',
         'MINUS', 'TIMES', 'DIVIDE', 'COMMA', 'SEMICOLON', 'LBRACE', 'RBRACE',
         'RPAREN', 'LPAREN')
 t_RBRACE           = r'\}'
 t_COMMA            = r','
 t_EQUALS           = r'='
+t_SEMICOLON        = r';'
+t_COLON            = r':'
 
-precedence = (
-    ('left','+','-'),
-    ('left','*','/'),
-    #('right','UMINUS'),
-)
+
+def t_FUNCTION(t):
+    r'function'
+    return t
 
 def t_ID(t):
     r'[a-z]+[0-9]?' #only lowercase.
 simpleinput="""
 vars(x=1, name="ahmed")
 if(name=="ahmed", {
-    print('yes!)')
+    print('yes!')
 
 })
 while(x<10, {
     
 })
  """
+funcline="function sum()={print('hello');}"
+lexer= lex.lex()
  
- 
-lexer= lex.lex()
-
-lexer.input(simpleinput)
-for tok in lexer:
-    print tok #print tok.type, " => ", tok .value, "at (%d, %d)"%(tok.lineno, tok.lexpos)
+if __name__=="__main__":
+   
+    lexer.input(funcline)
+    #lexer.input(simpleinput)
+    for tok in lexer:
+        print tok #print tok.type, " => ", tok .value, "at (%d, %d)"%(tok.lineno, tok.lexpos)
+'''
+Created on Mar 3, 2012
+
+@author: xmonader
+'''
+from ply import yacc
+from lexer import *
+#program : blocks
+#blocks: block*
+#block: statements
+#statements: statement*
+#statement: expr | funccall | funcdef
+#funccall: ID(argslist)(.funcall(argslist)*)
+#argslist
+#expr: term + expr
+#    |  term - expr
+#term: factor * term
+#    | factor / term
+#factor: NUMBER
+#      | ID
+
+
+    
+precedence = (
+    ('left','PLUS','MINUS'),
+    ('left','TIMES','DIVIDE'),
+    ('right','UMINUS'),
+)
+
+def p_block(p):
+    """block : stmtlist
+             | innerblock
+    """
+    print p[1]
+    p[0]=None
+    
+def p_innerblock(p):
+    """innerblock : LBRACE stmtlist RBRACE
+                 | LBRACE RBRACE
+    """
+    p[0]=('INNERBLOCK', p[2])
+    
+def p_stmtlist(p):
+    """stmtlist : stmtlist SEMICOLON stmt
+                | stmt
+    """
+    #print type(p)
+    stmtlist=[]
+    if len(p)==2:
+        stmtlist.append(p[1])
+    else:
+        for el in [p[1], p[3]]:
+            if isinstance(el, list):
+                stmtlist.extend(el)
+            else:
+                stmtlist.append(el)
+        
+    #for s in stmtlist: 
+    #    print s, type(s)
+    
+    stmts = [ x for x in stmtlist] #if x is not None]
+    print "stmtslist", stmts
+    #print "codeblock"
+    p[0]=stmts
+    
+
+def p_stmt_funccall(p):
+    """
+        stmt : ID LPAREN argslist RPAREN
+    """
+    funcname=p[1]
+    argslist=p[3]
+    print "calling func: ", funcname
+    print "with args: ", argslist
+    p[0]=('FUNCCALL', funcname, argslist)
+    
+
+def p_argslist(p):
+    """
+        argslist : argslist COMMA expr
+                | expr
+                |
+    """ 
+    args=[]
+    if len(p)==1:
+        p[0]=args
+        return
+
+    if len(p)==2:
+        args.append(p[1])
+    else:
+        for el in [p[1], p[3]]:
+            if isinstance(el, list):
+                args.extend(el)
+            else: 
+                args.append(el)
+    p[0]=args
+
+def p_funcdef(p):
+    """funcdef : ID LPAREN argslist RPAREN EQUALS FUNCTION innerblock
+    """
+    print "lenp:", len(p)
+    fname=p[1]
+    print "fname: ", fname
+    args=p[3]
+    print "with params:", args
+    innerblock=p[7]
+    p[0]=('FUNC', innerblock)
+
+def p_stmt_funcdef(p):
+    """stmt : funcdef"""
+    p[0]=p[1]
+def p_stmt_expr(p):
+    'stmt : expr'
+    p[0] = p[1]
+
+def p_stmt(p):
+    'stmt : '
+
+def p_expression_uminus(p):
+    "expr : '-' expr %prec UMINUS"
+    p[0] = -p[2]
+    
+def p_expression_plus(p):
+    'expr : expr PLUS term'
+    p[0] = p[1] + p[3]
+
+def p_expression_minus(p):
+    'expr : expr MINUS term'
+    p[0] = p[1] + p[3]
+    
+def p_expression_term(p):
+    'expr : term'
+    p[0] = p[1]
+#
+def p_factor_variable(p):
+    'factor : ID'
+    p[0]=p[1]
+def p_term_times(p):
+    'term : term TIMES factor'
+    p[0] = p[1] * p[3]
+    
+def p_term_div(p):
+    'term : term DIVIDE factor'
+    p[0] = p[1] / p[3]
+    
+def p_term_factor(p):
+    'term : factor'
+    p[0] = p[1]
+    
+def p_factor_number(p):
+    'factor : NUMBER'
+    p[0] = p[1]
+
+def p_factor_expr(p):
+    'factor : LPAREN expr RPAREN'
+    p[0] = p[2]
+    
+def p_error(p):
+    print "Syntax error"
+
+if __name__=="__main__":
+    #line="{1+20 + (3+2)*5 ;  3+5; 6+1;}"
+    #line="{ print(5,3,6+6) ; 1+2; 5+2}"
+    line="f(x,y)=function{print(3)}"
+    p=yacc.yacc()
+    p.parse(line, debug=False)
+