【问题标题】:How to manage semantic rule of declaration of variable in bison如何管理bison中变量声明的语义规则
【发布时间】:2019-02-04 02:07:41
【问题描述】:

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

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");
     }
  }
}

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

%{
  #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;
   }
}

我是野牛语法用于语义管理的初学者,在以下作品中我对相对语义规则有疑问:

  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 函数中?)请原谅我,但我是一个初学者,关于语义的很多事情我都不清楚。我希望你有耐心帮助我,我提前谢谢你。

【问题讨论】:

    标签: parsing compiler-construction bison symbol-table semantic-analysis


    【解决方案1】:

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

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

    这是一个用于 Decaf 语言的 Bison/Flex 编译器示例,它可能会给你一些想法https://github.com/davidcox143/Decaf-Compiler

    【讨论】:

    • 你好@Garrigan,我很抱歉,当时我创建了 ast,现在我无法理解如何处理与之相关的语义。您发布给我的指南在语义方面有点混乱。此外,我正在创建一个翻译器,而不是一个编译器。您能告诉我在创建 ast 之后如何在编程级别继续管理与解析器语法的每个产生相关的语义吗?谢谢,我希望你能给我一些其他的指导。
    • 编译器是经过优化的翻译器,所以编译器和编译器是一样的,只是跳过优化的那一步
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-02
    相关资源
    最近更新 更多