如何管理野牛变量声明的语义规则 [英] How to manage semantic rule of declaration of variable in bison

查看:109
本文介绍了如何管理野牛变量声明的语义规则的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须构建一个将Java语言转换为pyhton的编译器.我正在使用Flex和Bison工具.我创建了flex文件,并在Bison中定义了我必须实现的一些限制(例如数组,循环管理,类管理,逻辑算术运算符管理等)的语法语法. 我在理解如何处理语义规则时遇到了麻烦.例如,我应该处理import语句和变量声明的语义,在符号表中添加变量,然后处理翻译. 这是symboltable.h模块中符号表的结构:

I have to build a compiler that translates the java language into pyhton. I'm using the Flex and Bison tools. I created the flex file and I defined the syntactic grammar in Bison for some restrictions that I have to implement (such as array, management of cycles, management of a class, management of logical-arithmetic operators, etc.). I'm having trouble understanding how to handle semantic rules. For example, I should handle the semantics for import statement and variable declaration, add the variable in the symbol table and then handle the translation. This is the structure of the symbol table in the symboltable.h module:

struct symtable{

  char *scopename;            // key 
  struct symtable2 *subtable; // symble table secondary
  UT_hash_handle hh;          // to make the structure hash

}

struct symtable2            // secondary symbol structure
{

  char *name;               // Name of the symbol (key)
  char *element;            // it can be a variable or an array
  char *type;               // Indicates the type assumed by the token 
  (int, float, char, bool)
  char *value;              // value assigned to the variable
  int dim;                  // Array size, it is zero in the case of a variable.
  UT_hash_handle hh;        // to make the structure hash

};

这是添加符号功能:

void add_symbol( char *name, char *current_scopename, char *element, char *current_type, char *current_value, int dim, int nr) {    //Function to add a new symbol in the symbol table

  struct symtable *s;
  HASH_FIND_PTR(symbols, current_scopename, s);
  if (s == NULL) {
     s = (struct symtable *)malloc(sizeof *s);
     s->scopename =current_scopename;
     s->subtable=NULL;
     s->scopename =current_scopename;
     HASH_ADD_KEYPTR(hh,symbols,s->scopename,strlen(s->scopename),s);
  }
  struct symtable2 *s2;
  HASH_FIND_PTR(symbols2, name, s2);
  if (s2==NULL) {
     s2 = (struct symtable2 *)malloc(sizeof *s2);
     s2->name = name;
     s2->element = element;
     s2->type = current_type;
     s2->value = current_value;
     s2->dim = dim;
     HASH_ADD_KEYPTR(hh,s->subtable,s2->name,strlen(s2->name),s2);
  } else {
     if (strcmp( s2->type,current_type) == 0){
        s2->value =current_value;
     } else {
      printf("\033[01;31mRiga %i. [FATALE] SEMANTIC ERROR: assignment violates the primitive type of the variable.\033[00m\n", nr);
      printf("\n\n\033[01;31mParsing failed.\033[00m\n");
     }
  }
}

这是野牛文件的一部分,具有处理导入语句和变量声明的语法:

This is a part of the bison file with the grammar to handle import statement and the variable declaration:

%{
  #include <stdio.h>;
  #include <ctype.h>;
  #include <symboltable.h>;
  file *f_ptr;
%}

%start program
%token NUMBER
%token ID
%token INT
%token FLOAT
%token DOUBLE
%token CHAR
%token IMPORT

%right ASSIGNOP
%left SCOR
%left  SCAND
%left  EQ NE
%left  LT GT LE GE
%left ADD SUB
%left MULT DIV MOD
%right NOT
%left '(' ')' '[' ']'

%%

program
        : ImportStatement GlobalVariableDeclarations
        ;

ImportStatement
               :  IMPORT LibraryName ';'  { delete_file (); f_ptr = open_file (); fprintf(fptr, "import array \n"); }
               ;

LibraryName
           : 'java.util.*'
           ;

GlobalVariableFieldDeclarations
                               : type GlobalVariableDeclarations ';' 
                               ;


GlobalVariableDeclarations
                          : GlobalVariableDeclaration
                          | GlobalVariableDeclarations ',' GlobalVariableDeclaration
                          ;

GlobalVariableDeclaration
                         : VariableName 
                         | VariableName ASSIGNOP VariableInitializer {if (typeChecking($1,$3)== 0) {$1= $3; $$=$1;}}
                         ;

VariableName
            : ID {$$ = $1 ;}
            ;

type
    : INT
    | CHAR
    | FLOAT
    | DOUBLE
    | BOOLEAN
    ;

VariableInitializers
                    : VariableInitializer
                    | VariableInitializers ',' VariableInitializer
                    ;
VariableInitializer
                    : ExpressionStatement
                    ;

ExpressionStatement
                   : VariableName
                   | NUMBER
                   | ArithmeticExpression
                   | RelationalExpression
                   | BooleanExpression
                   ; 
ArithmeticExpression
                    : ExpressionStatement ADD ExpressionStatement
                    | ExpressionStatement SUB ExpressionStatement
                    | ExpressionStatement MULT ExpressionStatement
                    | ExpressionStatement DIV ExpressionStatement
                    | ExpressionStatement MOD ExpressionStatement
                    ;

RelationalExpression
                    : ExpressionStatement GT ExpressionStatement
                    | ExpressionStatement LT ExpressionStatement
                    | ExpressionStatement GE ExpressionStatement
                    | ExpressionStatement LE ExpressionStatement
                    | ExpressionStatement EQ ExpressionStatement
                    | ExpressionStatement NE ExpressionStatement
                    ;

BooleanExpression
                 : ExpressionStatement SCAND ExpressionStatement
                 | ExpressionStatement SCOR ExpressionStatement
                 | NOT ExpressionStatement
                 ;

%%

int yyerror (char *s)
{
  printf ("%s \n",s);
}

int main (void) {
  return yyparse();
}

int typeChecking (variable1, variable2) {
   struct symtable2 *s2;

   s2=find_symbol (scopename, variable1);
   if (s2!=NULL) {
       int type1= s2->type;
       char element1 = s2->element;
   }
   else{
       printf("\n\n\033[01;31mVariable 1 not defined.\033[00m\n");
       return -1;
   }

   s2=find_symbol (scopename, variable2);
   if (s2!=NULL) {
       int type2= s2->type;
       char element2 = s2->element;
   }
   else{
       printf("\n\n\033[01;31mVariable 2 not defined.\033[00m\n");
       return -1;
   }

   if(element1=='variable' && element2=='variable'){

       if (type1 == type2){
          return 0;
       }
       else {
          return 1;
       }
   }

   else {
       printf("\n\n\033[01;31m Different elements.\033[00m\n");
       return -1;
   }
}

我是野牛语法的初学者,负责语义管理,在以下作品中,我对相对语义规则感到怀疑:

I am a beginner with the syntax of the bison for the management of semantics, on the following productions I have doubts about the relative semantic rule:

  GlobalVariableFieldDeclarations
                               : type GlobalVariableDeclarations ';' 
                               ;


  GlobalVariableDeclarations
                          : GlobalVariableDeclaration
                          | GlobalVariableDeclarations ',' GlobalVariableDeclaration
                          ;

  GlobalVariableDeclaration
                          : VariableName 
                          | VariableName ASSIGNOP VariableInitializer {if (typeChecking($1,$3)== 0) {$1= $3; $$=$1;}}
                         ;

  VariableName
             : ID {$$ = $1 ;}
             ;

以这种方式为GlobalVariableDeclaration生产管理语义是否正确?以及如何通过add_symbol函数在符号表中插入所需的参数值? (或者更好的是,如何从生产开始获取所需的参数,以将其插入到已实现的add_symbol函数中?)原谅我,但我是一个初学者,关于语义的许多事情对我来说并不明确.希望您有耐心帮助我,在此先感谢您.

Is it correct to manage semantics in this way for a GlobalVariableDeclaration production? And how can I insert the required parameter values, in the symbol table, via the add_symbol function? (Or better, how can I acquire the required parameters starting from productions to insert them in the add_symbol function that I have implemented?) Forgive me but I am a beginner, and many things about the semantics are not clear to me. I hope you have the patience to help me, I thank you in advance.

推荐答案

您应该使用Bison来构建AST,然后您将在树上而不是在语法上执行语义分析.建立AST可以让您对更复杂的数据结构进行分析,而不仅仅是在Bison中建立的语法规则.

You should use Bison to build an AST and then you would perform semantic analysis on the tree instead of in the grammar. Building an AST allows you to perform analysis on more complex data structures then just the grammar rules you built in Bison.

一旦输入了AST,就可以制定规则,以将AST转换为具有相同语法的python程序.

Once you have your AST for the input you can then make rules for how to convert that AST into a python program with the same syntax.

以下是针对Decaf语言的Bison/Flex编译器示例,可能会给您一些想法 https ://github.com/davidcox143/Decaf-Compiler

Here is an example of a Bison/Flex compiler for the Decaf language that might give you some ideas https://github.com/davidcox143/Decaf-Compiler

这篇关于如何管理野牛变量声明的语义规则的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆