Bison 和 Flex 在编译和执行过程中的语法问题

问题描述 投票:0回答:1

我目前正在从事一个项目,该项目包括使用 Bison 和 Flex 解析代表机票的文本文件的内容。我创建了两个文件,ticket.y 和 ticket.l,来定义语法规则和相应的正则表达式。

我要分析的示例文件如下(

ExampleAirplaneTicket.txt
):

DOSSIER YBNUKR 
ANTOINE/DESAINT-EXUPERY
22/01/16 OS412  CDG 10:00  VIE 12:00    2:00
22/01/16 OS051  VIE 13:20  NRT +07:25   11:05 
23/01/16 OS8577 NRT 10:00  CHI 09:00    01:45

这是我的

billet.l
ticket.l
)文件的内容:

%{
#include "billet.tab.h"
void yyerror(const char *s);
%}

// Define the patterns for digits, alphabetic characters, and separators (spaces or tabs)
DIGIT [0-9]
ALPHA [A-Za-z]
SEP [ \t]

%%

// Define the rules for each token
"DOSSIER"               { return DOSSIER; }                   // Return DOSSIER token when the text "DOSSIER" is matched
{ALPHA}{6}              { return CODE_DOSSIER; }              // Return CODE_DOSSIER token when exactly 6 alphabetic characters are matched
{ALPHA}+("/"{ALPHA}+)?("-"{ALPHA}+)?  { yylval.sval = strdup(yytext); return NOM_PRENOM; } // Return NOM_PRENOM token for names and surnames with optional "/" and "-" separators
{DIGIT}{2}"/"{DIGIT}{2}"/"{DIGIT}{2} { return DATE; }         // Return DATE token when a date in the format DD/MM/YY is matched
{ALPHA}{2}{DIGIT}{2,4}  { return NUM_VOL; }                   // Return NUM_VOL token when a flight number (2 alphabetic characters followed by 2 to 4 digits) is matched
{ALPHA}{3}              { return CODE_AEROPORT; }             // Return CODE_AEROPORT token when a 3-letter airport code is matched
{DIGIT}{2}":"{DIGIT}{2} { return HEURE; }                     // Return HEURE token when a time in the format HH:MM is matched
"+"                     { return PLUS; }                       // Return PLUS token when a plus sign is matched
{DIGIT}{2}":"{DIGIT}{2} { return DUREE_VOL; }                 // Return DUREE_VOL token when a flight duration in the format HH:MM is matched
{SEP}+                  { /*ignore spaces and tabs*/ }         // Ignore spaces and tabs
\n                      { return NEWLINE; }                    // Return NEWLINE token when a newline character is matched
.                       { fprintf(stderr, "Caractère non autorisé: '%s'\n", yytext); exit(1); } // Catch any unrecognized characters and print an error message

%%

这是我的

billet.y
ticket.y
)文件的内容:

%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void yyerror(const char *s);
int yylex();
%}

%union {
  char *sval;
}

%token DOSSIER CODE_DOSSIER NEWLINE PLUS
%token <sval> DATE NUM_VOL CODE_AEROPORT HEURE DUREE_VOL
%token <sval> NOM_PRENOM

%type <sval> nom_prenom
%type <sval> heure_arrivee
%type <sval> heure_avec_plus

%%

// Start rule: billet
billet: DOSSIER CODE_DOSSIER NEWLINE infos_passager NEWLINE vols;

// Rule to match passenger information
infos_passager: nom_prenom '/' nom_prenom NEWLINE { printf("Infos passager : %s / %s\n", $1, $3); };

// Rule to match multiple flight entries
vols: vol NEWLINE vols | vol NEWLINE;

// Rule to match a single flight entry
vol: DATE NUM_VOL CODE_AEROPORT HEURE CODE_AEROPORT heure_arrivee DUREE_VOL { printf("Vol : %s %s %s %s %s %s %s\n", $1, $2, $3, $4, $5, $6, $7); };

// Rule to match arrival hour, either with or without a plus sign
heure_arrivee: heure_avec_plus | HEURE;

// Rule to match arrival hour with a plus sign
heure_avec_plus: PLUS HEURE { $$ = $2; };

// Rule to match name and surname tokens
nom_prenom: NOM_PRENOM;

%%

// Main function to start parsing
int main() {
    yyparse();
    return 0;
}

// Error handling function
void yyerror(const char *s) {
    fprintf(stderr, "Erreur de syntaxe : %s\n", s);
}

当我编译所有东西时,我无法在

ExampleAirplaneTicket.txt
文件上测试我的程序。 我只是有一个语法错误,尽管进行了多次尝试,但我仍无法解决这些问题,甚至无法弄清楚它的来源。

我正在寻求帮助来理解和解决这些问题。如果您对如何解决这些错误有任何建议或意见,我将不胜感激。

我尝试使用 Flex 和 Bison 实现一个解析器来解析表示机票信息的特定文本格式。我编写了 .l 和 .y 文件,并根据之前的问题进行了必要的调整。现在我希望程序能够成功编译并解析文件 ExampleAirlineTicket.txt 而不会出现任何语法错误或其他问题。除了当我测试文件时我只是得到一个语法错误,但不知道它来自哪里。

当我编译

billet.l
时,我收到这个警告(我认为这不是问题):

billet.l:17: warning, the rule can't match
billet.l:20: warning, the rule can't match

我编译

billet.y
时没有警告,当我用gcc编译所有东西时也没有。

但是当我使用 txt 文件进行测试时,我得到了这个:

Syntax error
flexbox syntax-error bison yacc lex
1个回答
0
投票

来自 flex 的以下警告:

billet.l:17: warning, the rule can't match
billet.l:20: warning, the rule can't match

来自以下规则:

  • NOM_PRENOM
    涵盖了
    CODE_AEROPORT
  • 规则所期望的内容
  • HEURE
    令牌与
    DUREE_VOL
  • 的规则相同的模式

所以,一些标记(

CODE_AEROPORT
DUREE_VOL
)永远不会出现。这可能是您收到默认“语法错误”消息的原因。

注意:bison生成的C源文件显示,当上报的token数(yycount内部变量)为0时,报“Syntax error”:

/*
[...]
     - The only way there can be no lookahead present (in yychar) is if
       this state is a consistent state with a default action.  Thus,
       detecting the absence of a lookahead is sufficient to determine
       that there is no unexpected or expected token to report.  In that
       case, just report a simple "syntax error".
[...]
*/
[...]
  switch (yycount)
    {
# define YYCASE_(N, S)                      \
      case N:                               \
        yyformat = S;                       \
      break
      YYCASE_(0, YY_("syntax error"));
      YYCASE_(1, YY_("syntax error, unexpected %s"));
      YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
      YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
      YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
      YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
# undef YYCASE_
    }
© www.soinside.com 2019 - 2024. All rights reserved.