Я не уверен, как выводить (сложную) полезную информацию, когда в моем парсере bison

Я пишу Flex/Bison Lexer/Parser, чтобы разобрать сценарий моего собственного дизайна в качестве задания для университета. Все идет очень хорошо, и мой скрипт правильно анализирует, обнаруживает любые ошибки и т. Д., И распознает токены, и передает семантические значения.

Однако я немного не уверен, как перевести это в полезную информацию... Мне просто нужно вывести простой текст, который сам по себе достаточно прост, однако я борюсь с логикой, где это сделать в yacc.

Например, скажем, мой yacc выглядит примерно так:

statement : 
   DRAW shape AT location  { printf("Draw shape at location"); } 
;

shape : 
   CUBE 
  | PYRAMID
  | SPHERE 
; 

location : 
   '(' NUMBER ',' 'NUMBER' ',' 'NUMBER' ')' { int x = $2; int y = $4; int z = $6;
                                              printf("%d,%d,%d",x,y,z); 
; 

Что я хотел бы сделать, так это распечатать что-то вроде drawShape(shape, x, y, z); - но я не уверен, как вернуть семантические значения из местоположения в оператор или как получить, был ли найденный токен формы кубом, пирамидой или сферой.

На данный момент оператор печати в месте срабатывает первым, поэтому мой вывод выглядит примерно так:

1,2,3Нарисовать фигуру на месте

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


person Eilidh    schedule 08.01.2012    source источник
comment
Я пошел дальше и использовал переменные для сохранения любых значений, которые я хочу использовать в своем операторе вывода, который отлично работает, однако мне было бы интересно более элегантное решение, если оно есть :) (Или узнать, наивен ли я и это уже лучшее решение!)   -  person Eilidh    schedule 09.01.2012


Ответы (2)


Обычный способ состоит в том, чтобы каждое действие создавало структуру данных, которая возвращается через $$ и используется последующими действиями. Например, у вас может быть

%union {
    int      ival;
    struct {
        int  x,y,z;
    }        coord;
}

%token<ival>  NUMBER
%type<coord>  location

%%

statement:
    DRAW shape AT location { printf("Draw shape at (%d,%d,%d)\n", $4.x, $4.y, $4.z); }
;

location:
    '(' NUMBER ',' NUMBER ',' NUMBER ')'  { $$.x = $2; $$.y = $4; $$.z = $6; }
;
person Chris Dodd    schedule 09.01.2012
comment
Спасибо! Полезно знать на будущее! :) - person Eilidh; 09.01.2012

Я пошел дальше и изменил это на -

statement:
    DRAW shape AT location {printf("Draw shape at (%d, %d, %d)",x,y,z); }
;

location :
    '(' NUMBER ',' NUMBER ',' NUMBER ')' {x=$2; y=$4; z=$6); 
; 

Это работает правильно, однако мне было бы интересно, есть ли более элегантное решение?

person Eilidh    schedule 08.01.2012
comment
Проблема в том, что он не масштабируется — например, если вы хотите добавить оператор DRAW FROM location TO location для рисования линии, два местоположения столкнутся с глобальными переменными x, y и z... - person Chris Dodd; 09.01.2012
comment
Да, это была разумная незавершенная работа, поскольку мой язык прост; но я предположил, что это было слишком грязно. Отлично, что есть альтернатива - спасибо! - person Eilidh; 09.01.2012