C 如何将合成属性传递到Ox中的下一个树节点

C 如何将合成属性传递到Ox中的下一个树节点,c,bison,yacc,lex,symbol-table,C,Bison,Yacc,Lex,Symbol Table,我正在使用现有的bison/yacc解析器(以及lex lexer)编写一个属性语法,并努力理解Ox系统的一个关键概念 在这个简化的示例中,我的程序是一系列接口s。我使用符号表st来跟踪解析树中的符号。现在我想检查接口的名称是否不在范围内,如果不在范围内,则将其放入范围内,并将该信息传递给程序的其余部分 但是,Ox抱怨没有指定某些属性,并且在继承和合成属性方面存在冲突;虽然我理解这意味着什么,但我看不出我如何能以不同的方式做到这一点,除了删除间接层和获得极其复杂的解析器/属性语法 你能给我指一下

我正在使用现有的bison/yacc解析器(以及lex lexer)编写一个属性语法,并努力理解Ox系统的一个关键概念

在这个简化的示例中,我的程序是一系列
接口
s。我使用符号表
st
来跟踪解析树中的符号。现在我想检查
接口的名称是否不在范围内,如果不在范围内,则将其放入范围内,并将该信息传递给
程序的其余部分

但是,
Ox
抱怨没有指定某些属性,并且在继承和合成属性方面存在冲突;虽然我理解这意味着什么,但我看不出我如何能以不同的方式做到这一点,除了删除间接层和获得极其复杂的解析器/属性语法

你能给我指一下这里的正确方向吗

我已经查找了教程,但除了源代码中的示例之外,没有发现任何使用ox的内容(但是没有使用符号表),并且ox引用在某些方面有点神秘

这是我的语法:

%{
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

int yylex(void);
void yyerror(char *);
extern int line_number;

typedef struct {
    string* names;
    void**  vals;
    string* types;
    int     len;
    int     maxlen;
} st;
%}

%start Program

%token INTERFACE END CLASS IMPLEMENTS VAR METHOD INT RETURN IF THEN ELSE
%token WHILE DO NOT AND NEW THIS _NULL EOC SCOL COL BRACL BRACR DOT COMMA 
%token ASSIGNMENT PLUS ASTERISK MINUS LT EQ DEC HEX ID NEWLINE

@attributes { st st; } Program Interface Class MaybeIDs

%% 

Start: Program
     @{
     @i   @Program.st@ = init_st();
     @}

Program: INTERFACE Interface SCOL Program     
                @{ 
                @i @Interface.st@ = @Program.0.st@;
                @i @Program.1.st@ = @Interface.st@;
                @}
       ; 
 
Interface: ID COL 
           END
                @{ 
                @i   if(contains(@Interface.st@, $1))
                        oxerror("%s already in scope", $1);
                @i   add(@Interface.st@, $1, "interface");
                @}
         ;  


%%


st init_st(){
    struct st newSt;
    //...
    return st;
}

st cpSt(st* st) {
    struct st newSt;
    // ...
    return newSt;
}


void add(st* table, string name, void* val, string type){
    // ...
}

boolean containsT(st* table, string name, string type){
    //...
    return true;
}

boolean contains(st* table, string name){
    //...
    return true;
}

void remove(st* table, string name) {
    //...
}

void oxerror(char* s) {
    fprintf(stderr, "Syntax Error line %i: %s\n", line_number, s);
    exit(3);
}

void yyerror(char *s) {
    fprintf(stderr, "Parse Error on line %i: %s\n", line_number, s);
    exit(2);
}

int main(void){
    yyparse();
}
%{
#包括
#包括
#包括
#包括
int yylex(无效);
无效错误(字符*);
外部内部线号;
类型定义结构{
字符串*名称;
无效**VAL;
字符串*类型;
内伦;
int-maxlen;
}st;
%}
%启动程序
%令牌接口端类实现VAR方法INT RETURN IF THEN ELSE
%标记而不新建此_NULLEOC SCOL COL BRACL BRACR点逗号
%令牌分配加星号减LT EQ DEC十六进制ID换行符
@属性{st;}程序接口类MaybeIDs
%% 
开始:程序
@{
@i@Program.st@=init_st();
@}
程序:接口SCOL程序
@{ 
@i@Interface.st@=@Program.0.st@;
@i@Program.1.st@=@Interface.st@;
@}
; 
接口:ID COL
结束
@{ 
@i if(包含(@Interface.st@,$1))
oxerror(“%s已在范围内”$1);
@我加上(@Interface.st@,$1,“Interface”);
@}
;  
%%
st init_st(){
struct st newSt;
//...
返回st;
}
st cpSt(st*st){
struct st newSt;
// ...
返回newSt;
}
void add(st*表,字符串名称,void*val,字符串类型){
// ...
}
布尔containsT(st*表、字符串名称、字符串类型){
//...
返回true;
}
布尔包含(st*表,字符串名称){
//...
返回true;
}
void remove(st*表,字符串名称){
//...
}
无效oxerror(字符*s){
fprintf(标准,“语法错误行%i:%s\n”,行号,s);
出口(3);
}
无效错误(字符*s){
fprintf(stderr,“第%i行上的分析错误:%s\n”,第\u行编号,s);
出口(2);
}
内部主(空){
yyparse();
}