Я пытаюсь написать транспилер с помощью python, но я могу прочитать и преобразовать только одну строку кода

#python #yacc #lex #transpiler #ply

Вопрос:

 lexer = lex.lex()  precedence = (  ('left', 'ADD', 'SUB'),  ('left', 'MULTI', 'DIV'),  ('left', 'RPAREN', 'LPAREN') )   def p_expression_term(p):  '''  expression : term ENDOFLINE  | var_assign ENDOFLINE  | empty  '''   p[0] = p[1]   def p_expression_empty(p):  'empty : '  pass   def p_expression_add(p):  'term : term ADD term'      def p_expression_sub(p):  'term : term SUB term'     def p_term_multi(p):  '''term : term MULTI term '''     def p_term_div(p):  '''term : term DIV term'''     def p_term_pow(p):  'term : term POW term'  p[0] = pow(p[1], p[3])   def p_term_factor(p):  'term : factor'  p[0] = p[1]   def p_factor_num(p):  'factor : NUMBER'  p[0] = ['number' p[1]]   def p_expressionParenth(p):  '''term : LPAREN term RPAREN'''  p[0] = p[2]  pass   def p_var_assign1(p):  '''var_assign : NAME EQUAL NAME  | NAME EQUAL term  '''   p[0] = ast_tree.ast_name1(p[1], p[3])   def p_var_assignBe(p):  '''var_assign : LET NAME BE term'''      def p_var_assign3(p):  '''var_assign : NAME IDENTIFIER EQUAL term'''      # Error rule for syntax errors def p_error(p):  print("Syntax error in input! at "   str(p))    # Build the parser parser = yacc.yacc()  while True:  try:  s = '''let x be 12;'''   except EOFError:  break  if not s: continue   result = parser.parse(s)  result = ast_tree.fill_locations(result)  print(ast.unparse(result))  exit()  

Я пытаюсь написать транспилер с помощью python ply, но могу прочитать и преобразовать только одну строку кода. это мой код класса yacc. в настоящее время я анализирую код в методе expression_term. Я пробовал некоторые другие решения, которые я нашел на github, но это не сработало. как я могу запустить и проанализировать несколько строк в одном вводе, можете ли вы дать мне фрагмент кода для этого ? Спасибо.

Ответ №1:

Ваша грамматика принимает только одно выражение, поэтому синтаксический анализатор делает именно то, что вы ему велели. Если вы хотите, чтобы он анализировал несколько выражений, вам нужна грамматика, которая определяет синтаксис списка. Это может выглядеть примерно так:

 program : empty  | program expression  

Вам придется удалить пустую продукцию из expression , потому что несколько последовательных пустых объектов неоднозначны (сколько пустых строк в пустой последовательности?). И вам нужно убедиться program , что это начальный символ.

Комментарии:

1. большое спасибо, я пытаюсь это сделать, но это дает только бесконечную ошибку рекурсии.

2. @beton: это, вероятно, означает, что вы пропустили базовый случай ( program : empty ).