Удаление обнуляемых производств

Я работаю над созданием лексического анализатора для подмножества паскаля, который является программным проектом, рекомендованным в конце учебника "Красный дракон". Я работаю через изменение грамматики в LL, чтобы я мог создать таблицу разбора. Я игнорирую висящую еще двусмысленность и считаю, что это была единственная присутствующая двусмысленность. Я только что удалил все произведения эпсилон. Прежде чем перейти к левому факторингу, я хотел узнать, правильно ли я удалил продукцию epsilon. Я долго смотрел на это, поэтому действительно не уверен, что пропустил что-то, что позже вызовет проблемы, и у меня нет никого, кто бы мог это проверить. Я знаю, что это длинный пост, я действительно не знаю, куда еще пойти, чтобы проверить это кем-то, кто знает. Я очень ценю ваше время!

Оригинальная грамматика:

<statement> →
    if <expression> then <statement>
<factor> → id
<program> →
     <program> id (<identifier_list>);
     <declarations>
     <subprogram_declarations>
     <compound_statement>
     .
<identifier_list> →
     id
     | <identifier_list>, id
<declarations> →
     <declarations> var id : <type>;
     |E
<type> → 
     <standard_type>
     |array[num..num] of <standard_type>
<standard type> →
     integer
     | real
<subprogram_declarations> →
     <subprogram_declarations> <subprogram_declaration>;
     |E
<subprogram_declaration> →
     <subprogram_head declarations> 
     <subprogram_declarations> 
     <compound_statement>
<subprogram_head> → 
     function id <arguments> : <standard_type>;
<arguments> → 
    (<parameter_list>)
    | E
<parameter_list> →
     id : <type> 
     | <parameter_list>; id : <type>
<compound statement> →
     begin
     <optional_statements>
     end
<optional_statements> →
     <statement_list>
     | E
<statement_list> →
     <statement>
     |<statement_list>; <statement>
<statement> →
     <variable> assignop <expression>
     | <procedure_statement>
     | <compound_statement>
     | if <expression then statement> else <statement>
     | while <expression> do <statement>
     | if <expression> then <statement>
<variable> → 
     id
     | id [<expression> ]
<expression_list> →
     <expression>
     |<expression_list> , <expression>
<expression> →
     <simple_expression>
     | <simple_expression> relop <simple_expression>
<simple_expression> →
     <term>
     | sign <term>
     | <simple_expression> addop <term>
<term> →
     <factor>
     | <term> mulop <factor>
<factor> →
     id
     | id (<expression_list>)
     | num
     | (<expression>)
     | not <factor>
     | id [<expression>]
<sign> →
     + | -

Устранение производства грамматики после эпсилона

<statement> →
    if <expression> then <statement>
<factor> → id
<program> →
     <program><id (<identifier_list>);
     <declarations>
     <subprogram_declarations>
     .
     |<program> id (<identifier_list>);
      <subprogram_declarations>
      .
     |<program>id (<identifier_list>);
      <declarations>
      .
     |<program> id (<identifier_list>);
      .
     |<program><id (<identifier_list>);
      <declarations>
      <subprogram_declarations>
      begin
      <statement_list>
      end
      .
     |<program> id (<identifier_list>);
      <subprogram_declarations>
      begin
      <statement_list>
      end
      .
     |<program>id (<identifier_list>);
      <declarations>
      begin
      <statement_list>
      end
      .
     |<program> id (<identifier_list>);
      begin
      <statement_list>
      end
      .
<identifier_list> →
     id
     | <identifier_list>, id
<declarations> →
     <declarations> var id : <type>;
<type> → 
     <standard_type>
     |array[num..num] of standard_type
<standard type> →
     <integer>
     | <real>
     <subprogram_declarations> →
     <subprogram_declarations>  <subprogram_declaration>;
<subprogram_declaration> →
     <subprogram_head> <declarations> 
     <subprogram_declarations >
     begin
     <statement_list>
     end
     |<subprogram_head>
      <subprogram_declarations >
      begin
      <statement_list>
      end
     |<subprogram_head> <declarations> 
      begin
      <statement_list>
      end
     |<subprogram_head>
      begin
      <statement_list>
      end
     |<subprogram_head> <declarations> 
      <subprogram_declarations >
     |<subprogram_head>
      <subprogram_declarations >
     |<subprogram_head> <declarations> 
     |<subprogram_head>
<subprogram_head> → 
      function id (<parameter_list>) : <standard_type>;
      |function id : <standard_type>;
<parameter_list> →
     id : <type> 
     |<parameter_list>; id : <type>
<statement_list> →
     <statement>
     |<statement_list>;< statement>
<statement> →
     <variable> assignop <expression>
     | <procedure_statement>
     | <compound_statement>
     | if <expression> then <statement> else <statement>
     | while <expression> do <statement>
     | if <expression> then <statement>
<variable> → 
     id
     |id [<expression>]
<expression_list> →
     <expression>
     |<expression_list> , <expression>
<expression> →
     <simple_expression>
     | <simple_expression> relop <simple_expression>
<simple_expression> →
     <term>
     | <sign> <term>
     | <simple_expression> addop <term>
<term> →
     <factor>
     | <term> mulop <factor>
<factor> →
     id
     | id (<expression_list>)
     | num
     | (<expression>)
     | not <factor>
     | id [<expression>]
<sign> →
     + | -

Конечно, вторая грамматика существенно отличается. Я удалил все произведения epsilon, найдя ссылки на него и создав | Вариант с и без него. При удалении эпсилона осталась только одна строка в производственном процессе, я полностью удалил это производство и переместил линию туда, где производство было вызвано ранее. Например, я полностью исключил этот способ, изменив с:

 <subprogram_head> → 
      function id <arguments> : <standard_type>;
 <arguments> → 
      (<parameter_list>)
      | E

в

<subprogram_head> → 
     function id (<parameter_list>) : <standard_type>;
     |function id : <standard_type>;

0 ответов

Другие вопросы по тегам