Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Flex/Bison解析器识别;(“与”不同;_C_Compiler Construction_Bison_Flex Lexer - Fatal编程技术网

C Flex/Bison解析器识别;(“与”不同;

C Flex/Bison解析器识别;(“与”不同;,c,compiler-construction,bison,flex-lexer,C,Compiler Construction,Bison,Flex Lexer,我正在尝试使用flex和bison编写一个玩具语言的简单解析器,它基本上只支持变量和算术函数 目前,我面临一个奇怪的问题,即带有开括号和下一个标记之间的空格的语句与带有开括号且下一个标记之间没有空格的语句的工作方式不同,特别是我正在尝试识别以下程序 var b: int begin b <- (4) end 其中p3.txt是一个文本文件,其中包含要解析的程序。无法解释这一点。您必须跟踪标记和缩减。只需返回所有这些单字符标记的*yytext,并在语法中按字面意思使用它们,例如,就更简单、

我正在尝试使用flex和bison编写一个玩具语言的简单解析器,它基本上只支持变量和算术函数

目前,我面临一个奇怪的问题,即带有开括号和下一个标记之间的空格的语句与带有开括号且下一个标记之间没有空格的语句的工作方式不同,特别是我正在尝试识别以下程序

var b: int
begin
b <- (4)
end

其中p3.txt是一个文本文件,其中包含要解析的程序。

无法解释这一点。您必须跟踪标记和缩减。只需返回所有这些单字符标记的
*yytext
,并在语法中按字面意思使用它们,例如
,就更简单、可读性更强了(“
。这样一来,非法字符也会变成语法错误,这使得yacc能够更好地恢复错误,而不是简单地忽略它。NUMFLOAT规则中的
需要被引用。大多数表达式语法将
因子
分解为一个较低的
级别,而
符号项
位于错误的级别el,它应该在缺少的
级别,并且应该是
符号主
stmnt\u列表
应该是左递归的,而不是右递归的,用于LR解析。好的,在添加了之间的引号之后。在NUMFLOAT中,问题消失了,你知道是什么导致了它吗?。表示除\n、 所以空格也认为
匹配任何字符,除非你引用它,所以它匹配空格,然后下面的数字让解析器看到
(NUMFLOAT NUMINT…
。如果NUMFLOAT规则只匹配
,则无论如何都是错误的。它应该坚持在某个地方至少有一个数字,通常在小数点之后:
{digit}*“{digit}+
%{
#include<stdlib.h>
#include<math.h>
#include "parser.tab.h"
%}

LETTR   [a-zA-Z]
DIGIT   [0-9]
BIN     [0-1] 
SIMB   [$|_]
WHITESPACE [ \t\r]+ 

%%
WHITESPACE  { }
"\n"    {yylineno++;}
"begin"  {return BEGN;}
"if"     {return IF;}
"ifelse" {return IFELSE;}
"while"  {return WHILE;}
"end"                           {return END;}
"var"             {return VAR;}
"read"            {return READ;}
"print"           {return PRINT;}
"int"             {return INT;}
"float"           {return FLOAT;}
"<-"                            {return ASSIGN;}
({SIMB}|{LETTR})({LETTR}|{DIGIT}|{SIMB})*  {yylval.id=(char*)malloc(strlen(yytext)+1); strcpy(yylval.id, yytext); return ID;} /* Identificador */
({DIGIT})({DIGIT})*   {return NUMINT;}   /*Entero*/
({DIGIT})*.({DIGIT})({DIGIT})*     {return NUMFLOAT;} /*Punto Flotante*/
";"                             {return SEMICOLON;}
":"               {return COLON;}
"+"                             {return PLUS;}
"-"                             {return MINUS;}
"*"                             {return MULT;}
"/"                             {return DIVIDE;}
"<"                             {return LESSTHAN;}
">"                             {return GREATTHAN;}
"="                             {return EQUALS;}
"<="                            {return LESSEQUALS;}
">="                            {return GREATEQUALS;}
"~"               {return NEGSIGN;}
"("                             {return LEFTP;}
")"                             {return RIGHTP;}
.                 { }
%%
%{
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
FILE extern *yyin;
char extern *yytext;
int yylineno;
int yylex();
int yyerror(char const * s);
void addToTable(char * var);
void initTable();
void checkVar();
void printTable();


%}
%union{
  char *id;
}
%token <id > ID
%token BEGN IF IFELSE WHILE END VAR ASSIGN LEFTP RIGHTP INT FLOAT SEMICOLON COLON PLUS MINUS 
MULT DIVIDE LESSTHAN GREATTHAN EQUALS LESSEQUALS GREATEQUALS NUMINT NUMFLOAT READ PRINT NEGSIGN
%start prog


%%

prog: opt_decls BEGN opt_stmts END {printf("Valid program!\n"); printTable(); return 0;}

opt_decls: decls
          | /* empty */
;

decls : dec SEMICOLON decls
      | dec
;

dec : VAR ID COLON tipo { addToTable($2);}
;

tipo : INT 
     | FLOAT
;

stmt : ID ASSIGN expr {checkVar($1);}
     | IF LEFTP expression RIGHTP stmt
     | IFELSE LEFTP expression RIGHTP stmt stmt
     | WHILE LEFTP expression RIGHTP stmt
     | READ ID {checkVar($2);}
     | PRINT expr
     | BEGN opt_stmts END
;

opt_stmts : stmt_lst
          | /*empty*/
;

stmt_lst : stmt SEMICOLON stmt_lst
          | stmt
;

expression : expr
           | expr relop expr
;

expr : expr PLUS term
     | expr MINUS term
     | sign term
     | term  

term : term MULT factor
     | term DIVIDE factor
     | factor
; 

factor : LEFTP expr RIGHTP 
       | ID {checkVar($1);}
       | NUMINT
       | NUMFLOAT
;

relop : LESSTHAN 
      | GREATTHAN 
      | EQUALS 
      | LESSEQUALS 
      | GREATEQUALS 
;

sign : NEGSIGN
;

%%
char symbolTable [100][50];

int yyerror(char const * s) {
  fprintf(stderr, "%s at line: %d while reading %s\n", s, yylineno, yytext);
}

void printTable(){
  printf("Symbol table:\n");
  int i; 
  for (i = 0; i < 100; i++){
    if (strcmp(symbolTable[i], "") != 0){
      printf("%s\n", symbolTable[i]);
    }
  }
}

void addToTable(char *var){
  int i = 0;
  for (i = 0; i < 100; i++){
    if (strcmp(symbolTable[i], "") == 0){
      strcpy(symbolTable[i], var);
      break;    
    }
  }
}

void initTable(){
  int i;
  for (i = 0; i < 100; i++){
    strcpy(symbolTable[i], "");
  }
}

void checkVar(char * var){
  int i;
  for (i = 0; i < 100; i++){
    if (strcmp(symbolTable[i], var) == 0){
      return;
    } 
  }
  char errorMsg [255];
  sprintf(errorMsg, "Variable %s was not initialized", var);
  yyerror(errorMsg);
  exit(-1);
}

void main(int argc, char *argv[]) {

  initTable();  
  if (argc == 1)
        printf("Input file not found.\n");
        else{
            yyin = fopen(argv[1], "r");
      yyparse();
        } 

  fclose(yyin);
}
flex parser.lex
bison -d parser.y
gcc lex.yy.c parser.tab.c -lfl
./a.out p3.txt