Bison/Flex C 在解析第二个令牌时遇到问题

问题描述

我正在做一项作业,我必须制作 Bison/Flex 应用程序,该应用程序将在每个案例的末尾附加 while/if 案例作为注释。我已经设法将所有组件编译在一起,但无论我做什么,在尝试解析第二个标记后总是会引发错误

我使用的是 Windows 版本的 Bison 和 Flex(分别为 2.4.1 和 2.5.4a-1)

这是我的 lex 文件 commentAdder.l

Dim objExcelApp As Excel.Application
Dim objExcelWorkbook As Excel.Workbook
Dim objExcelWorksheet As Excel.Worksheet

Sub ExportAllHyperlinksInMultipleEmailsToExcel()
Dim objSelection As Selection
Dim objMail As MailItem
Dim objMailDocument As Word.Document   << Added Word. here
Dim objHyperlink As Word.Hyperlink     << Added Word. here
Dim i As Long

Set objSelection = outlook.application.ActiveExplorer.Selection

If Not (objSelection Is nothing) Then

   Set objExcelApp = CreateObject("Excel.Application")
   Set objExcelWorkbook = objExcelApp.Workbooks.Add
   Set objExcelWorksheet = objExcelWorkbook.Sheets(1)
   objExcelApp.Visible = True
   objExcelWorkbook.Activate

   With objExcelWorksheet
            .Cells(1,1) = "Email"
            .Cells(1,2) = "Text"
            .Cells(1,3) = "Link"
            .Cells(1,4) = "Source"
  End With

  i = 0
  For Each objMail In objSelection
      Set objMailDocument = objMail.GetInspector.WordEditor
      If objMailDocument.Hyperlinks.Count > 0 Then
         For Each objHyperlink In objMailDocument.Hyperlinks
             If InStr(objHyperlink.Address,"www.") > 0 Then
                i = i + 1
                Call ExportToExcel(i,objMail,objHyperlink)
             End If
         Next
      End If
      objMail.Close oldiscard
  Next

  objExcelWorksheet.Columns("A:D").AutoFit
End If
End Sub

Sub ExportToExcel(n As Long,objCurrentMail As MailItem,objCurrentHyperlink As Word.Hyperlink) << Added Word. here
    Dim nLastRow As Integer
 
    nLastRow = objExcelWorksheet.Range("A" & objExcelWorksheet.Rows.Count).End(xlUp).Row + 1


objExcelWorksheet.Range("A" & nLastRow) = n
objExcelWorksheet.Range("B" & nLastRow) = objCurrentHyperlink.TextTodisplay
objExcelWorksheet.Range("C" & nLastRow) = objCurrentHyperlink.Address
objExcelWorksheet.Range("D" & nLastRow) = objCurrentMail.Subject
End Sub

还有我的解析器 commentAdder.y

%{
#include "commentAdder.tab.h"
%}

%option noyywrap

CLOSE "}"
CASE ("while"|"if"|"switch")(" "|"")("(".+")")(" {"|"{")
CODE .+

%%

{CLOSE} {yylval.s=yytext; return CLOSE;}
{CASE}  {yylval.s=yytext; return CASE;}
{CODE}  {yylval.s=yytext; return CODE;}

%%

我猜测 expr 在第一次解析后无处可去,没有进一步争论的余地,但我不知道如何解决这个问题,因为我是一个完全的新手,而且教程过于复杂和稀缺。

更新

在 Rici 的帮助下,我通过将解析器中的语法部分更改为以下内容解决此问题:

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

#define MAX_DEPTH 10
#define MAX_COMMENT_LENGTH 32

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

/* Local variables */
char heldComments[MAX_DEPTH][MAX_COMMENT_LENGTH] = {};
int currentDepth=-1;
%}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
%union {
  char* s;
}

%token <s> CASE CLOSE CODE
%type <s> expr

%% /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

expr    : CLOSE      {$$ = strcat($1,(char *)strcat((char *)"//",heldComments[currentDepth])); 
                      strcpy(heldComments[currentDepth],"");
                      printf("CLOSE: ",$1);
                      currentDepth=currentDepth-1;}
        | CASE       {$$=$1; currentDepth=currentDepth+1; strcpy(heldComments[currentDepth],$1); printf("CASE: ",$1);} 
        | CODE       {printf("CODE: ",$1);$$=$1;}
        ;

%% /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

void yyerror( char* s )
{
  fprintf(stderr,"Unexpected token: '%s'\n",yytext);
  exit(1);
}

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

现在我遇到了一个完全不同的问题,其中 strcat 出于某种原因导致应用程序过早结束,大概是由于某种错误

解决方法

正如我在更新中所说的,我已经解决了主要问题。至于 strcat 问题,我不得不使用额外的 char[] 变量而不是处理原始 char* 的