У меня есть сканер и синтаксический анализатор, с использованием гибких и бизонов.Содержимое идентификатора доступа при использовании пользовательского типа в 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; }
Еще раз спасибо.
Если вы используете зубров, то почему это помечено 'yacc'? –
Просто маленький вопрос, не связанный с вашей проблемой, но почему вы создаете узлы для вещей, которые ему не нужны? Как вместо создания нового узла для 'conditioal', почему бы просто не просто установить' $$ 'на' $ 1'? Это немного упростит ваше дерево и приведет к меньшему количеству узлов в нем. –
@ScottHunter Тег 'flex' предназначен для [Apache Flex] (http://flex.apache.org/) не клона GNU lex, поэтому я удалил его. –