2016-11-02 12 views
0

У меня есть сканер и синтаксический анализатор, с использованием гибких и бизонов.Содержимое идентификатора доступа при использовании пользовательского типа в Bison

Анализатор строит дерево непосредственно в действиях, и сделать так, что я создал-структуру под названием STreeNode и я использую

#define YYSTYPE_IS_DECLARED 
typedef STreeNode* YYSTYPE; 

структура является:

typedef struct tagSTreeNode 
{ 
    EOperationType type; 
    int count; 
    struct tagSTreeNode **children; 
    char *string; 
} STreeNode; 

Есть как 40 токенов, и для каждого правила у меня есть что-то вроде

unlabeled_statement: 
     assignment               {$$ = createNode(eUNLABELED_STATEMENT, 1, $1);} 
     | function_call_statement           {$$ = createNode(eUNLABELED_STATEMENT, 1, $1);} 
     | goto                {$$ = createNode(eUNLABELED_STATEMENT, 1, $1);} 
     | return               {$$ = createNode(eUNLABELED_STATEMENT, 1, $1);} 
     | conditional              {$$ = createNode(eUNLABELED_STATEMENT, 1, $1);} 
     | repetitive              {$$ = createNode(eUNLABELED_STATEMENT, 1, $1);} 
     | empty_statement             {$$ = createNode(eUNLABELED_STATEMENT, 1, $1);} 
     ; 

Подпись для createNode functi on is

STreeNode *createNode(EOperationType type, int count, ...) { 

Дерево работает нормально. Проблема заключается в доступе к реальному значению для имен переменных, имен функций и т. Д. Поскольку YYSTYPE является структурой, $ x не имеет строкового значения, которое я хочу сохранить в элементе char * string в структуре.

У меня есть% token, называемый IDENTIFIER, а другой называется INTEGER, и те должны получать значения, которые я хочу.

Исследование, я обнаружил, что могу попробовать и использовать union {}, чтобы иметь каждый токен определенного типа. Может быть, это может помочь? И если это так, мне обязательно нужно будет указать тип каждого единственного токена? Как это можно реализовать?

А как насчет yytext? Нельзя ли использовать эту цель для достижения этой цели?

Спасибо!

--- EDIT -

Так я создал

%union { 
    char *string; 
    STreeNode *node; 
} 

и конкретизированы каждый терминал и нон тип терминала, чтобы быть одним из них. Узлы все еще работают, но строки, использующие (например, $ 1), возвращают значение null.

Нужно ли мне что-либо менять в сканере? Мой сканер имеет:

[a-zA-Z][a-z0-9A-Z]*  { return IDENTIFIER; } 
[0-9]+      { return INTEGER; } 

Еще раз спасибо.

+0

Если вы используете зубров, то почему это помечено 'yacc'? –

+0

Просто маленький вопрос, не связанный с вашей проблемой, но почему вы создаете узлы для вещей, которые ему не нужны? Как вместо создания нового узла для 'conditioal', почему бы просто не просто установить' $$ 'на' $ 1'? Это немного упростит ваше дерево и приведет к меньшему количеству узлов в нем. –

+0

@ScottHunter Тег 'flex' предназначен для [Apache Flex] (http://flex.apache.org/) не клона GNU lex, поэтому я удалил его. –

ответ

0

Если у ваших жетонов есть набор типов для них, лексеру необходимо задать yylval соответствующему типу. Что-то вроде:

[a-zA-Z][a-z0-9A-Z]*  { yylval.string = strdup(yytext); return IDENTIFIER; } 
[0-9]+      { yylval.string = strdup(yytext); return INTEGER; }