Я пытаюсь создать Лексер и Парсер для проекта, я уже сделал Лексер, и теперь я пытаюсь сделать парсер
Лексер:
reserved = {
'if' : 'IF',
'else' : 'ELSE',
'while' : 'WHILE',
'do' : 'DO',
'for' : 'FOR',
'main' : 'MAIN',
'int' : 'INT_ID',
'float' : 'FLOAT_ID',
'char' : 'CHAR_ID'
}
tokens = ['CHAR', 'FLOAT','INTEGER', 'PLUS', 'MINUS', 'MUL', 'DIV','OPEN_PAR', 'CLOSE_PAR','OPEN_BRACKETS','CLOSE_BRACKETS','ASSIGNMENT', 'EQUALS', 'NOT_EQUALS', 'EQUAL_OR_GREATER_THAN',
'EQUAL_OR_LESS_THAN', 'LESS_THAN', 'GREATER_THAN', 'COMMA', 'SEMI_COLON','IDENTIFIER','NEWLINE','COMMENT_EOL',"COMMENT_DELIMITED"] + list(reserved.values())
t_PLUS = r'\+'
t_MINUS = r'-'
t_MUL = r'\*'
t_DIV = r'/'
t_OPEN_PAR = r'\('
t_CLOSE_PAR = r'\)'
t_OPEN_BRACKETS = r'\{'
t_CLOSE_BRACKETS = r'\}'
t_ASSIGNMENT = r'\='
t_EQUALS = r'\=\='
t_NOT_EQUALS = r'\!\='
t_EQUAL_OR_GREATER_THAN = r'\>\='
t_EQUAL_OR_LESS_THAN = r'\<\='
t_LESS_THAN = r'\<'
t_GREATER_THAN = r'\>'
t_COMMA = r'\,'
t_SEMI_COLON = r'\;'
def t_COMMENT_EOL(t):
r'\/{2}.*\n'
return t
def t_COMMENT_DELIMITED(t):
r'\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\/'
return t
def t_CHAR(t):
r'\'[a-zA-Z]\''
return t
def t_FLOAT(t):
r'[-]?[0-9]*\.{1}[0-9]+'
t.value = float(t.value)
return t
def t_INTEGER(t):
r'\d+'
t.value = int(t.value)
return t
def t_IDENTIFIER(t):
# r'(^[a-zA-Z0-9]*\_{1}[0-9]*$)*'
r'[a-zA-Z0-9\_]+'
t.type = reserved.get(t.value,'IDENTIFIER') # Check for reserved words
return t
def t_newline(t):
r'\n+'
t.lexer.lineno += len(t.value)
t_ignore = ' \t'
def t_error(t):
print("Illegal character '%s'" % t.value[0])
t.lexer.skip(1)
lexer = lex.lex()
Парсер (Некоторые правила еще не созданы):
# Get the token map from the lexer. This is required.
from lexer import tokens
#valorvariaveis
def p_float(p):
'float : FLOAT'
p[0] = p[1]
def p_integer(p):
'int : INTEGER'
p[0] = p[1]
def p_char(p):
'char : CHAR'
p[0] = p[1]
def p_id(p):
'id : IDENTIFIER'
p[0] = p[1]
#fim valorvariaveis
#decl_var
def p_decl_var(p):
'decl_var : type id SEMI_COLON'
p[0] = p[1]
#tipovariaveis
def p_INT_ID(p):
'type : INT_ID'
p[0] = p[1]
def p_FLOAT_ID(p):
'type : FLOAT_ID'
p[0] = p[1]
def p_CHAR_ID(p):
'type : CHAR_ID'
p[0] = p[1]
#program
def p_program(p):
'program : INT_ID MAIN OPEN_PAR CLOSE_PAR'
#block
def p_block(p):
'block : OPEN_BRACKETS decl_var command CLOSE_BRACKETS'
p[0] = p[1]
#command
def p_command_basic_command(p):
'command : basic_command'
p[0] = p[1]
def p_command_iteration(p):
'command : iteration'
p[0] = p[1]
def p_command(p):
'command : IF OPEN_PAR expr_relacional CLOSE_PAR command OPEN_BRACKETS ELSE command CLOSE_BRACKETS'
p[0] = p[1]
#basic_command
def p_basic_command_assignment(p):
'basic_command : assignment'
p[0] = p[1]
def p_basic_command_block(p):
'basic_command : block'
p[0] = p[1]
#iteration
def p_iteration_WHILE(p):
'iteration : WHILE OPEN_PAR expr_relacional CLOSE_PAR command'
#FALTA FAZER AQUIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
p[0] = p[1]
def p_iteration_DO(p):
'iteration : DO command WHILE OPEN_PAR expr_relacional CLOSE_PAR SEMI_COLON'
#FALTA FAZER AQUIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
p[0] = p[1]
#atribuicao
def p_assignment(p):
'assignment : id ASSIGNMENT expression_arit SEMI_COLON'
p[0] = p[1]
#oprelacional
def p_op_relacional_GREATER_THAN(p):
'op_relacional : GREATER_THAN'
p[0] = p[1]
def p_op_relacional_LESS_THAN(p):
'op_relacional : LESS_THAN'
p[0] = p[1]
def p_op_relacional_EQUAL_OR_LESS_THAN(p):
'op_relacional : EQUAL_OR_LESS_THAN'
p[0] = p[1]
def p_op_relacional_EQUAL_OR_GREATER_THAN(p):
'op_relacional : EQUAL_OR_GREATER_THAN'
p[0] = p[1]
#expr_relacional
def p_expr_relacional(p):
'expr_relacional : expression_arit op_relacional expression_arit'
print("oioioi")
if p[2] == '>=':
if p[1] >= p[3]:
p[0]=True
else:
p[0]=False
elif p[2] == '<=':
if p[1] <= p[3]:
p[0]=True
else:
p[0]=False
elif p[2] == '<':
if p[1] < p[3]:
p[0]=True
else:
p[0]=False
elif p[2] == '>':
if p[1] > p[3]:
p[0]=True
else:
p[0]=False
#expression_arit
def p_expression_arit_plus(p):
'expression_arit : expression_arit PLUS term'
p[0] = p[1] + p[3]
def p_expression_arit_minus(p):
'expression_arit : expression_arit MINUS term'
p[0] = p[1]- p[3]
def p_expression_arit(p):
'expression_arit : term'
p[0] = p[1]
#fim expression_arit
#term
def p_term_mul(p):
'term : term MUL factor'
p[0] = p[1] * p[3]
def p_term_div(p):
'term : term DIV factor'
p[0] = p[1] / p[3]
def p_term_factor(p):
'term : factor'
p[0] = p[1]
#fim term
#fator
def p_factor_expr(p):
'factor : OPEN_PAR expression_arit CLOSE_PAR'
p[0] = p[2]
def p_factor_integer(p):
'factor : int'
p[0] = p[1]
def p_factor_float(p):
'factor : float'
p[0] = p[1]
def p_factor_id(p):
'factor : id'
p[0] = p[1]
def p_factor_char(p):
'factor : char'
p[0] = p[1]
# Error rule for syntax errors
def p_error(p):
print("Syntax error in input!")
# Build the parser
parser = yacc.yacc()
while True:
try:
s = input('calc > ')
except EOFError:
break
if not s: continue
result = parser.parse(s)
print(result)
Что происходит, так это то, что единственное принимаемое правило - первое (плавающее), все остальные недостижимы, и я не знаю, почему
calc > 1.0
1.0
calc > 1
Syntax error in input!
None
calc >
Вы видите введенное «1.0», и анализатор не выдает ошибок сообщения, но когда я пытаюсь ввести целое число, например «1», он выдает ошибку.
Но есть правило для чисел типа INTEGER