2014-10-26 4 views
1

Я работаю над этой грамматикой, чтобы построить SDD для проверки типа или аналогичного. Вчера я провел работу над структурами данных и синтаксическим анализом, но я всегда делал ошибку сегментации. Мне кажется, что YACC (бизон) теряет ценности среди редукций.yacc теряет значения среди редукций

Таким образом, я решил создать более простую грамматику с более простыми действиями. Кажется, что ценности теряются среди одного сокращения, а другое, или, может быть, я делаю что-то неправильно? В этом примере лексерская часть не имеет отношения к делу, поэтому я пропустил ее.

После грамматики с ее действиями и результата против ожидаемого результата ..

D: T VAR SEMICOLON D    { 
            printf("processing D -> T var ; D\n"); 
            printf("\tvalue of T is %f\n", $1); 
           } 
|/*empty*/      { 
            printf("processing D -> empty\n"); 
           } 
; 

T: B        { 
            printf("processing B inside T\n"); 
            printf("\tvalue of B is %f\n", $1); 
           } 

C        { printf("processing C inside T\n"); 
            printf("processing T-> B C\n"); 
            printf("\tvalue of B is %f\n", $1); 
            printf("\tvalue of C is %f\n", $<dbl>2); 
            $$ = $1 + $<dbl>2; 

           } 
| RECORD '{' D '}'    { printf("processing record { D }\n");} 
; 

B: INT       { printf("processing B -> int\n"); 
            $$ = 1; 
           } 
| FLOAT       { printf("processing B -> float\n"); 
            $$ = 1; 
           } 
; 

C: /*empty*/      { printf("processing C -> empty\n"); 
            printf("\tsetting C to be equal to 1\n"); 
            $$=1; 
           } 
| LBRACK NUM RBRACK C   { int n = $2; 
            printf("processing C -> [%d] C\n", n); 
            double d = $4; 
            printf("\tprevious C value is %f\n", d); 
            double f = d+ 1; 
            printf("\tnew value of $$ is %f\n", f); 
            $$ = f; 
           } 
; 

это выход для входа как int [12][3] ciao;

processing B -> int 
processing B inside T 
    value of B is 1.000000 
processing C -> empty 
    setting C to be equal to 1 
processing C -> [3] C 
    previous C value is 1.000000 
    new value of $$ is 2.000000   
processing C -> [12] C      
    previous C value is 2.000000   
    new value of $$ is 3.000000   
processing C inside T 
processing T-> B C 
    value of B is 1.000000 
    value of C is 0.000000    (*) 
processing D -> empty 
processing D -> T var ; D 
    value of T is 1.000000    (*) 

Как вы можете увидеть значение теряется среди C, отмеченные знаком * Я ожидаю, что он вырастет, например,

processing B -> int 
processing B inside T 
    value of B is 1.000000 
processing C -> empty 
    setting C to be equal to 1 
processing C -> [3] C 
    previous C value is 1.000000 
    new value of $$ is 2.000000   
processing C -> [12] C      
    previous C value is 2.000000   
    new value of $$ is 3.000000   
processing C inside T 
processing T-> B C 
    value of B is 1.000000 
    value of C is 3.000000     
processing D -> empty 
processing D -> T var ; D 
    value of T is 4.000000     

ЛЮБОЙ совет приветствуется, а также объяснение и предложение достичь объема, есть ли что-нибудь, что мне не хватает?

+0

В производстве T-> C имеется только один элемент, и вы ссылаетесь на два в семантическом действии. – user3344003

+0

Нет! обратите внимание, что между ними нет трубы .. Производство T-> B C .. – LMG

ответ

3

Производство для T выглядит следующим образом, значительно упрощается .:

T: B { /* Mid Rule Action (MRA) */ } C { $$ = $1 + $2; } 

В заключительном действии для T, то $2 относится к MRA, поскольку СВП подсчитывают с точки зрения производства в. (Фактически, MRA заменяется не-терминалом с пустым RHS.) Таким образом, C - $3.

Поскольку MRA фактически не устанавливает значение, $2 несколько неуточнен, но 0 не слишком маловероятен.

Bison ручных ссылок:

Using Mid-Rule Actions:

Середины правило действий сами по себе считается одним из компонентов правила. Это имеет значение, когда есть другое действие позже в том же правиле (и, как правило, в конце есть другое): вы должны подсчитывать действия вместе с символами при разработке номера n для использования в $n.

Mid-Rule Action Translation: указывает на то, что «в середине правила действия фактически преобразуются в обычные правила и действия», а затем предоставляет ряд примеров пустых правил производства (и их внутренние имена, полезные для понимания зубров отладочную.)

+0

Ммм, я попробую .. Я не знал о таком рассмотрении .. Итак, yacc автоматически преобразует mra в один из таких что литература называет маркером? Я имею в виду то же самое, что T-> B M C, где M-> пустое и имеет действие, связанное (я думаю, вы назвали его пустым rhs)? – LMG

+0

@ LMG, да, точно. – rici

+0

Я очень рад, что вы помогли мне разобраться с этим. +1 и правильно ответьте чувак! – LMG

 Смежные вопросы

  • Нет связанных вопросов^_^