Основываясь на предыдущем посте , где вы спрашивали о модуле ply.lex, приведенный ниже фрагмент выглядит как частичная реализация c-подобной грамматики.Я не очень много использовал ply, но одна из хитростей заключается в том, что вам нужно определить правила грамматики в правильном порядке.
tokens = [ 'ID', 'NUMBER', 'LESSEQUAL', 'ASSIGN' ]
reserved = {
'while' : 'WHILE',
'then' : 'THEN',
'if' : 'IF'
}
tokens += reserved.values()
t_ignore = ' \t'
t_NUMBER = r'\d+'
t_LESSEQUAL = r'<='
t_ASSIGN = r'\='
def t_ID(t):
r'[a-zA-Z_][a-zA-Z0-9_]*'
if t.value in reserved:
t.type = reserved[ t.value ]
return t
def t_error(t):
print 'Illegal character'
t.lexer.skip(1)
def p_statement_assign(p):
'statement : ID ASSIGN expression'
p[0] = ('assign', p[1], p[3] )
def p_statement_if(p):
'statement : IF expression THEN statement'
p[0] = ('if', p[2], p[4] )
def p_statement_while(p):
'statement : WHILE expression THEN statement'
p[0] = ('while', p[2], p[4] )
def p_expression_simple(p):
'''expression : ID
| NUMBER'''
p[0] = p[1]
def p_expression_cmp(p):
'expression : expression LESSEQUAL expression'
p[0] = ( '<=', p[1], p[3] )
import ply.lex as lex
import ply.yacc as yacc
lexer = lex.lex()
parser = yacc.yacc()
inp = 'while h<=0 then t=1'
res = parser.parse(inp)
print res
Вывод из фрагмента:
('while', ('<=', 'h', '0'), ('assign', 't', '1'))