с несколькими переменными, такими как YYLVAL [duplicate]

Это не ответ на вопрос OP, а пример с игрушкой, чтобы проиллюстрировать ответ @ShikharDua, над которым я нашел очень полезным.

Хотя этот фрагмент тривиален, в фактических данных у меня было 1000 строк и много столбцов, и я хотел иметь возможность группировать по разным столбцам, а затем выполнять статистику ниже для более чем одного такета колонка. Таким образом, надежный метод построения кадра данных по одной строке за раз был большим удобством. Спасибо @ShikharDua!

import pandas as pd 

BaseData = pd.DataFrame({ 'Customer' : ['Acme','Mega','Acme','Acme','Mega','Acme'],
                          'Territory'  : ['West','East','South','West','East','South'],
                          'Product'  : ['Econ','Luxe','Econ','Std','Std','Econ']})
BaseData

columns = ['Customer','Num Unique Products', 'List Unique Products']

rows_list=[]
for name, group in BaseData.groupby('Customer'):
    RecordtoAdd={} #initialise an empty dict 
    RecordtoAdd.update({'Customer' : name}) #
    RecordtoAdd.update({'Num Unique Products' : len(pd.unique(group['Product']))})      
    RecordtoAdd.update({'List Unique Products' : pd.unique(group['Product'])})                   

    rows_list.append(RecordtoAdd)

AnalysedData = pd.DataFrame(rows_list)

print('Base Data : \n',BaseData,'\n\n Analysed Data : \n',AnalysedData)
16
задан neuromancer 5 December 2009 в 20:35
поделиться

2 ответа

Объявление %union изменяет тип yylval.

Руководство bison объясняет :

В обычном (нерентабельный) парсер, семантическое значение токена должно храниться в глобальной переменной yylval. Когда вы используете только один тип данных для семантических значений, yylval имеет этот тип. Таким образом, если тип int (по умолчанию), вы можете записать это в yylex:

...
yylval = value;  /* Put value onto Bison stack. */
return INT;      /* Return the type of the token. */
...

Когда вы используете несколько типов данных, тип yylval является объединением сделанные из объявления %union (см. раздел «Коллекция типов значений»). Поэтому, когда вы сохраняете значение токена, вы должны использовать правильный член объединения. Если объявление %union выглядит так:

%union {
  int intval;
  double val;
  symrec *tptr;
}

, тогда код в yylex может выглядеть следующим образом:

...
yylval.intval = value; /* Put value onto Bison stack. */
return INT;          /* Return the type of the token. */
...
11
ответ дан Greg Bacon 24 August 2018 в 18:34
поделиться

Цель union - разрешить сохранение объектов другого типа в узлах, испускаемых flex.

Чтобы лучше объяснить, вы можете иметь, например:

%union
{
    int intValue;
    float floatValue;
    char *stringValue;
}

в .y, если вы хотите обеспечить базовую поддержку типов int, float и string. Что вы можете сделать с этим?

Две вещи:

Во-первых, вы можете автоматически устанавливать правильные значения при создании токенов. Подумайте о файле .l предыдущего примера, вы можете:

[a-zA-Z][a-zA-Z0-9]* {
 yylval.stringValue = strdup(yytext);
 return IDENTIFIER;
}

[0-9]+ { 
 yylval.intValue = atoi(yytext);
 return INTEGER;
}

[0-9]*\.[0-9]+"f"? {
    yylval.floatValue = new atof(yytext);
 return FLOAT;
}

Кроме того, вы можете использовать значение непосредственно в вашей грамматике flex :

nexp: nexp '+' nexp { $<floatValue>$ = $<floatValue>1 + $<floatValue>3 }

Наконец, если вы планируете использовать дерево синтаксиса ООП, вы можете определить объединение как

%union
{
    class ASTNode *node;
}

, в котором ASTNode является классом предков любого типа синтаксического узла.

23
ответ дан Jack 24 August 2018 в 18:34
поделиться
  • 1
    Зачем определять объединение одного элемента? Почему не просто #define YYSTYPE class ASTNode * (если память служит). – Chris Lutz 6 December 2009 в 04:00
Другие вопросы по тегам:

Похожие вопросы: