“sizeof”对 Bison 生成的不完整类型“Comando”的无效应用

invalid application of ‘sizeof’ to incomplete type ‘Comando’ generated by Bison

我正在用 Bison 生成解释器。我有 3 个 class 想要使用,它们是 'Comando'、'Parametro' 和 'Mkdisk'(Comand,英文参数)。我生成了 .tab.cc 和 .tab.hh 文件,但是我收到这个特定 classes

的错误
parser.tab.hh:373:34: error: invalid application of ‘sizeof’ to incomplete type ‘Comando’
parser.tab.hh:376:36: error: invalid application of ‘sizeof’ to incomplete type ‘Parametro’

完整的错误日志是:

In file included from ./analizador/driver.h:2,
                 from ./analizador/driver.cc:3:
parser.tab.hh:373:34: error: invalid application of ‘sizeof’ to incomplete type ‘Comando’
parser.tab.hh:376:36: error: invalid application of ‘sizeof’ to incomplete type ‘Parametro’
parser.tab.hh: In instantiation of ‘void yy::Parser::semantic_type::destroy() [with T = Comando]’:
parser.tab.hh:568:43:   required from ‘void yy::Parser::basic_symbol<Base>::clear() [with Base = yy::Parser::by_type]’
parser.tab.hh:547:9:   required from ‘yy::Parser::basic_symbol<Base>::~basic_symbol() [with Base = yy::Parser::by_type]’
parser.tab.hh:662:22:   required from here
parser.tab.hh:342:17: error: invalid use of incomplete type ‘class Comando’
In file included from ./analizador/driver.h:2,
                 from ./analizador/driver.cc:3:
parser.yy:17:10: note: forward declaration of ‘class Comando’
In file included from ./analizador/driver.h:2,
                 from ./analizador/driver.cc:3:
parser.tab.hh: In instantiation of ‘void yy::Parser::semantic_type::destroy() [with T = Parametro]’:
parser.tab.hh:572:45:   required from ‘void yy::Parser::basic_symbol<Base>::clear() [with Base = yy::Parser::by_type]’
parser.tab.hh:547:9:   required from ‘yy::Parser::basic_symbol<Base>::~basic_symbol() [with Base = yy::Parser::by_type]’
parser.tab.hh:662:22:   required from here
parser.tab.hh:342:17: error: invalid use of incomplete type ‘class Parametro’
In file included from ./analizador/driver.h:2,
                 from ./analizador/driver.cc:3:
parser.yy:16:10: note: forward declaration of ‘class Parametro’
In file included from ./analizador/driver.h:2,
                 from ./analizador/driver.cc:3:
parser.tab.hh: In instantiation of ‘T& yy::Parser::semantic_type::emplace(U&& ...) [with T = Comando; U = {Comando}]’:
parser.tab.hh:324:7:   required from ‘void yy::Parser::semantic_type::move(yy::Parser::semantic_type::self_type&&) [with T = Comando; yy::Parser::semantic_type::self_type = yy::Parser::semantic_type]’
parser.tab.hh:1329:31:   required from ‘yy::Parser::basic_symbol<Base>::basic_symbol(yy::Parser::basic_symbol<Base>&&) [with Base = yy::Parser::by_type]’
parser.tab.hh:656:12:   required from here
parser.tab.hh:233:15: error: invalid use of incomplete type ‘class Comando’
In file included from ./analizador/driver.h:2,
                 from ./analizador/driver.cc:3:
parser.yy:17:10: note: forward declaration of ‘class Comando’
In file included from ./analizador/driver.h:2,
                 from ./analizador/driver.cc:3:
parser.tab.hh: In instantiation of ‘T& yy::Parser::semantic_type::emplace(U&& ...) [with T = Parametro; U = {Parametro}]’:
parser.tab.hh:324:7:   required from ‘void yy::Parser::semantic_type::move(yy::Parser::semantic_type::self_type&&) [with T = Parametro; yy::Parser::semantic_type::self_type = yy::Parser::semantic_type]’
parser.tab.hh:1333:33:   required from ‘yy::Parser::basic_symbol<Base>::basic_symbol(yy::Parser::basic_symbol<Base>&&) [with Base = yy::Parser::by_type]’
parser.tab.hh:656:12:   required from here
parser.tab.hh:233:15: error: invalid use of incomplete type ‘class Parametro’
In file included from ./analizador/driver.h:2,
                 from ./analizador/driver.cc:3:
parser.yy:16:10: note: forward declaration of ‘class Parametro’
In file included from /usr/include/c++/9/vector:67,
                 from parser.tab.hh:62,
                 from ./analizador/driver.h:2,
                 from ./analizador/driver.cc:3:
/usr/include/c++/9/bits/stl_vector.h: In instantiation of ‘std::_Vector_base<_Tp, _Alloc>::~_Vector_base() [with _Tp = Parametro; _Alloc = std::allocator<Parametro>]’:
/usr/include/c++/9/bits/stl_vector.h:569:7:   required from ‘T& yy::Parser::semantic_type::emplace(U&& ...) [with T = std::vector<Parametro>; U = {std::vector<Parametro, std::allocator<Parametro> >}]’
parser.tab.hh:324:7:   required from ‘void yy::Parser::semantic_type::move(yy::Parser::semantic_type::self_type&&) [with T = std::vector<Parametro>; yy::Parser::semantic_type::self_type = yy::Parser::semantic_type]’
parser.tab.hh:1354:46:   required from ‘yy::Parser::basic_symbol<Base>::basic_symbol(yy::Parser::basic_symbol<Base>&&) [with Base = yy::Parser::by_type]’
parser.tab.hh:656:12:   required from here
/usr/include/c++/9/bits/stl_vector.h:333:35: error: invalid use of incomplete type ‘class Parametro’
  333 |         _M_impl._M_end_of_storage - _M_impl._M_start);
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
In file included from ./analizador/driver.h:2,
                 from ./analizador/driver.cc:3:
parser.yy:16:10: note: forward declaration of ‘class Parametro’
In file included from /usr/include/c++/9/vector:65,
                 from parser.tab.hh:62,
                 from ./analizador/driver.h:2,
                 from ./analizador/driver.cc:3:
/usr/include/c++/9/bits/stl_construct.h: In instantiation of ‘void std::_Destroy(_ForwardIterator, _ForwardIterator) [with _ForwardIterator = Parametro*]’:
/usr/include/c++/9/bits/stl_construct.h:206:15:   required from ‘void std::_Destroy(_ForwardIterator, _ForwardIterator, std::allocator<_T2>&) [with _ForwardIterator = Parametro*; _Tp = Parametro]’
/usr/include/c++/9/bits/stl_vector.h:677:15:   required from ‘std::vector<_Tp, _Alloc>::~vector() [with _Tp = Parametro; _Alloc = std::allocator<Parametro>]’
parser.tab.hh:342:7:   required from ‘void yy::Parser::semantic_type::destroy() [with T = std::vector<Parametro>]’
parser.tab.hh:593:58:   required from ‘void yy::Parser::basic_symbol<Base>::clear() [with Base = yy::Parser::by_type]’
parser.tab.hh:547:9:   required from ‘yy::Parser::basic_symbol<Base>::~basic_symbol() [with Base = yy::Parser::by_type]’
parser.tab.hh:662:22:   required from here
/usr/include/c++/9/bits/stl_construct.h:133:51: error: static assertion failed: value type is destructible
  133 |       static_assert(is_destructible<_Value_type>::value,
      |                                                   ^~~~~
/usr/include/c++/9/bits/stl_construct.h:137:11: error: invalid use of incomplete type ‘std::iterator_traits<Parametro*>::value_type’ {aka ‘class Parametro’}
  136 |       std::_Destroy_aux<__has_trivial_destructor(_Value_type)>::
      |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  137 |  __destroy(__first, __last);
      |  ~~~~~~~~~^~~~~~~~~~~~~~~~~
In file included from ./analizador/driver.h:2,
                 from ./analizador/driver.cc:3:
parser.yy:16:10: note: forward declaration of ‘std::iterator_traits<Parametro*>::value_type’ {aka ‘class Parametro’}
In file included from ./analizador/driver.h:2,
                 from parser.yy:28:
parser.tab.hh:373:34: error: invalid application of ‘sizeof’ to incomplete type ‘Comando’
parser.tab.hh:376:36: error: invalid application of ‘sizeof’ to incomplete type ‘Parametro’
In file included from ./analizador/../Clases/Comando.h:5,
                 from parser.yy:30:
./analizador/../Clases/./parametro.h:7:7: error: redefinition of ‘class Parametro’
    7 | class Parametro {
      |       ^~~~~~~~~
In file included from parser.yy:29:
./analizador/../Clases/parametro.h:7:7: note: previous definition of ‘class Parametro’
    7 | class Parametro {
      |       ^~~~~~~~~
In file included from ./analizador/../Comandos/../Clases/Comando.h:5,
                 from ./analizador/../Comandos/Mkdisk.h:8,
                 from parser.yy:31:
./analizador/../Comandos/../Clases/./parametro.h:7:7: error: redefinition of ‘class Parametro’
    7 | class Parametro {
      |       ^~~~~~~~~
In file included from parser.yy:29:
./analizador/../Clases/parametro.h:7:7: note: previous definition of ‘class Parametro’
    7 | class Parametro {
      |       ^~~~~~~~~
In file included from ./analizador/../Comandos/Mkdisk.h:8,
                 from parser.yy:31:
./analizador/../Comandos/../Clases/Comando.h:9:7: error: redefinition of ‘class Comando’
    9 | class Comando {
      |       ^~~~~~~
In file included from parser.yy:30:
./analizador/../Clases/Comando.h:9:7: note: previous definition of ‘class Comando’
    9 | class Comando {
      |       ^~~~~~~
parser.yy: In member function ‘virtual int yy::Parser::parse()’:
parser.yy:69:19: error: ‘Mkdsik’ was not declared in this scope; did you mean ‘Mkdisk’?
parser.yy:69:27: error: ‘disco’ was not declared in this scope
In file included from ./analizador/driver.h:2,
                 from parser.yy:28:
parser.tab.hh: In instantiation of ‘T& yy::Parser::semantic_type::emplace(U&& ...) [with T = Comando; U = {}]’:
parser.tab.cc:649:41:   required from here
parser.tab.hh:233:15: error: no matching function for call to ‘Comando::Comando()’
In file included from parser.yy:30:
./analizador/../Clases/Comando.h:12:9: note: candidate: ‘Comando::Comando(std::string)’
   12 |         Comando(string);
      |         ^~~~~~~
./analizador/../Clases/Comando.h:12:9: note:   candidate expects 1 argument, 0 provided
./analizador/../Clases/Comando.h:9:7: note: candidate: ‘Comando::Comando(const Comando&)’
    9 | class Comando {
      |       ^~~~~~~
./analizador/../Clases/Comando.h:9:7: note:   candidate expects 1 argument, 0 provided
./analizador/../Clases/Comando.h:9:7: note: candidate: ‘Comando::Comando(Comando&&)’
./analizador/../Clases/Comando.h:9:7: note:   candidate expects 1 argument, 0 provided
In file included from ./analizador/driver.h:2,
                 from parser.yy:28:
parser.tab.hh: In instantiation of ‘T& yy::Parser::semantic_type::emplace(U&& ...) [with T = Parametro; U = {}]’:
parser.tab.cc:653:43:   required from here
parser.tab.hh:233:15: error: no matching function for call to ‘Parametro::Parametro()’
In file included from parser.yy:29:
./analizador/../Clases/parametro.h:9:9: note: candidate: ‘Parametro::Parametro(std::string, std::string)’
    9 |         Parametro(string, string);
      |         ^~~~~~~~~
./analizador/../Clases/parametro.h:9:9: note:   candidate expects 2 arguments, 0 provided
./analizador/../Clases/parametro.h:7:7: note: candidate: ‘Parametro::Parametro(const Parametro&)’
    7 | class Parametro {
      |       ^~~~~~~~~
./analizador/../Clases/parametro.h:7:7: note:   candidate expects 1 argument, 0 provided
./analizador/../Clases/parametro.h:7:7: note: candidate: ‘Parametro::Parametro(Parametro&&)’
./analizador/../Clases/parametro.h:7:7: note:   candidate expects 1 argument, 0 provided
In file included from ./analizador/driver.h:2,
                 from lexico.l:4:
parser.tab.hh:373:34: error: invalid application of ‘sizeof’ to incomplete type ‘Comando’
parser.tab.hh:376:36: error: invalid application of ‘sizeof’ to incomplete type ‘Parametro’
lexico.l: In function ‘yy::Parser::symbol_type yylex(Driver&)’:
lexico.l:20:34: error: no matching function for call to ‘yy::Parser::make_MKDISK()’
In file included from ./analizador/driver.h:2,
                 from lexico.l:4:
parser.tab.hh:940:7: note: candidate: ‘static yy::Parser::symbol_type yy::Parser::make_MKDISK(std::string)’
parser.tab.hh:940:7: note:   candidate expects 1 argument, 0 provided
lexico.l:23:32: error: no matching function for call to ‘yy::Parser::make_SIZE()’
In file included from ./analizador/driver.h:2,
                 from lexico.l:4:
parser.tab.hh:790:7: note: candidate: ‘static yy::Parser::symbol_type yy::Parser::make_SIZE(std::string)’
parser.tab.hh:790:7: note:   candidate expects 1 argument, 0 provided
lexico.l:24:29: error: no matching function for call to ‘yy::Parser::make_F()’
In file included from ./analizador/driver.h:2,
                 from lexico.l:4:
parser.tab.hh:805:7: note: candidate: ‘static yy::Parser::symbol_type yy::Parser::make_F(std::string)’
parser.tab.hh:805:7: note:   candidate expects 1 argument, 0 provided
lexico.l:25:32: error: no matching function for call to ‘yy::Parser::make_PATH()’
In file included from ./analizador/driver.h:2,
                 from lexico.l:4:
parser.tab.hh:820:7: note: candidate: ‘static yy::Parser::symbol_type yy::Parser::make_PATH(std::string)’
parser.tab.hh:820:7: note:   candidate expects 1 argument, 0 provided
lexico.l:26:29: error: no matching function for call to ‘yy::Parser::make_U()’
In file included from ./analizador/driver.h:2,
                 from lexico.l:4:
parser.tab.hh:835:7: note: candidate: ‘static yy::Parser::symbol_type yy::Parser::make_U(std::string)’
parser.tab.hh:835:7: note:   candidate expects 1 argument, 0 provided
lexico.l:29:31: error: no matching function for call to ‘yy::Parser::make_NUM()’
In file included from ./analizador/driver.h:2,
                 from lexico.l:4:
parser.tab.hh:775:7: note: candidate: ‘static yy::Parser::symbol_type yy::Parser::make_NUM(std::string)’
parser.tab.hh:775:7: note:   candidate expects 1 argument, 0 provided
lexico.l:30:30: error: no matching function for call to ‘yy::Parser::make_BF()’
In file included from ./analizador/driver.h:2,
                 from lexico.l:4:
parser.tab.hh:850:7: note: candidate: ‘static yy::Parser::symbol_type yy::Parser::make_BF(std::string)’
parser.tab.hh:850:7: note:   candidate expects 1 argument, 0 provided
lexico.l:31:30: error: no matching function for call to ‘yy::Parser::make_FF()’
In file included from ./analizador/driver.h:2,
                 from lexico.l:4:
parser.tab.hh:865:7: note: candidate: ‘static yy::Parser::symbol_type yy::Parser::make_FF(std::string)’
parser.tab.hh:865:7: note:   candidate expects 1 argument, 0 provided
lexico.l:32:30: error: no matching function for call to ‘yy::Parser::make_WF()’
In file included from ./analizador/driver.h:2,
                 from lexico.l:4:
parser.tab.hh:880:7: note: candidate: ‘static yy::Parser::symbol_type yy::Parser::make_WF(std::string)’
parser.tab.hh:880:7: note:   candidate expects 1 argument, 0 provided
lexico.l:33:29: error: no matching function for call to ‘yy::Parser::make_K()’
In file included from ./analizador/driver.h:2,
                 from lexico.l:4:
parser.tab.hh:895:7: note: candidate: ‘static yy::Parser::symbol_type yy::Parser::make_K(std::string)’
parser.tab.hh:895:7: note:   candidate expects 1 argument, 0 provided
lexico.l:34:29: error: no matching function for call to ‘yy::Parser::make_M()’
In file included from ./analizador/driver.h:2,
                 from lexico.l:4:
parser.tab.hh:910:7: note: candidate: ‘static yy::Parser::symbol_type yy::Parser::make_M(std::string)’
parser.tab.hh:910:7: note:   candidate expects 1 argument, 0 provided
lexico.l:35:32: error: no matching function for call to ‘yy::Parser::make_RUTA()’
In file included from ./analizador/driver.h:2,
                 from lexico.l:4:
parser.tab.hh:925:7: note: candidate: ‘static yy::Parser::symbol_type yy::Parser::make_RUTA(std::string)’
parser.tab.hh:925:7: note:   candidate expects 1 argument, 0 provided
In file included from ./analizador/driver.h:2,
                 from lexico.l:4:
parser.tab.hh: In instantiation of ‘void yy::Parser::semantic_type::destroy() [with T = Comando]’:
parser.tab.hh:568:43:   required from ‘void yy::Parser::basic_symbol<Base>::clear() [with Base = yy::Parser::by_type]’
parser.tab.hh:547:9:   required from ‘yy::Parser::basic_symbol<Base>::~basic_symbol() [with Base = yy::Parser::by_type]’
parser.tab.hh:662:22:   required from here
parser.tab.hh:342:17: error: invalid use of incomplete type ‘class Comando’
In file included from ./analizador/driver.h:2,
                 from lexico.l:4:
parser.yy:17:10: note: forward declaration of ‘class Comando’
In file included from ./analizador/driver.h:2,
                 from lexico.l:4:
parser.tab.hh: In instantiation of ‘void yy::Parser::semantic_type::destroy() [with T = Parametro]’:
parser.tab.hh:572:45:   required from ‘void yy::Parser::basic_symbol<Base>::clear() [with Base = yy::Parser::by_type]’
parser.tab.hh:547:9:   required from ‘yy::Parser::basic_symbol<Base>::~basic_symbol() [with Base = yy::Parser::by_type]’
parser.tab.hh:662:22:   required from here
parser.tab.hh:342:17: error: invalid use of incomplete type ‘class Parametro’
In file included from ./analizador/driver.h:2,
                 from lexico.l:4:
parser.yy:16:10: note: forward declaration of ‘class Parametro’
In file included from ./analizador/driver.h:2,
                 from lexico.l:4:
parser.tab.hh: In instantiation of ‘T& yy::Parser::semantic_type::emplace(U&& ...) [with T = Comando; U = {Comando}]’:
parser.tab.hh:324:7:   required from ‘void yy::Parser::semantic_type::move(yy::Parser::semantic_type::self_type&&) [with T = Comando; yy::Parser::semantic_type::self_type = yy::Parser::semantic_type]’
parser.tab.hh:1329:31:   required from ‘yy::Parser::basic_symbol<Base>::basic_symbol(yy::Parser::basic_symbol<Base>&&) [with Base = yy::Parser::by_type]’
parser.tab.hh:656:12:   required from here
parser.tab.hh:233:15: error: invalid use of incomplete type ‘class Comando’
In file included from ./analizador/driver.h:2,
                 from lexico.l:4:
parser.yy:17:10: note: forward declaration of ‘class Comando’
In file included from ./analizador/driver.h:2,
                 from lexico.l:4:
parser.tab.hh: In instantiation of ‘T& yy::Parser::semantic_type::emplace(U&& ...) [with T = Parametro; U = {Parametro}]’:
parser.tab.hh:324:7:   required from ‘void yy::Parser::semantic_type::move(yy::Parser::semantic_type::self_type&&) [with T = Parametro; yy::Parser::semantic_type::self_type = yy::Parser::semantic_type]’
parser.tab.hh:1333:33:   required from ‘yy::Parser::basic_symbol<Base>::basic_symbol(yy::Parser::basic_symbol<Base>&&) [with Base = yy::Parser::by_type]’
parser.tab.hh:656:12:   required from here
parser.tab.hh:233:15: error: invalid use of incomplete type ‘class Parametro’
In file included from ./analizador/driver.h:2,
                 from lexico.l:4:
parser.yy:16:10: note: forward declaration of ‘class Parametro’
In file included from /usr/include/c++/9/vector:67,
                 from parser.tab.hh:62,
                 from ./analizador/driver.h:2,
                 from lexico.l:4:
/usr/include/c++/9/bits/stl_vector.h: In instantiation of ‘std::_Vector_base<_Tp, _Alloc>::~_Vector_base() [with _Tp = Parametro; _Alloc = std::allocator<Parametro>]’:
/usr/include/c++/9/bits/stl_vector.h:569:7:   required from ‘T& yy::Parser::semantic_type::emplace(U&& ...) [with T = std::vector<Parametro>; U = {std::vector<Parametro, std::allocator<Parametro> >}]’
parser.tab.hh:324:7:   required from ‘void yy::Parser::semantic_type::move(yy::Parser::semantic_type::self_type&&) [with T = std::vector<Parametro>; yy::Parser::semantic_type::self_type = yy::Parser::semantic_type]’
parser.tab.hh:1354:46:   required from ‘yy::Parser::basic_symbol<Base>::basic_symbol(yy::Parser::basic_symbol<Base>&&) [with Base = yy::Parser::by_type]’
parser.tab.hh:656:12:   required from here
/usr/include/c++/9/bits/stl_vector.h:333:35: error: invalid use of incomplete type ‘class Parametro’
  333 |         _M_impl._M_end_of_storage - _M_impl._M_start);
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
In file included from ./analizador/driver.h:2,
                 from lexico.l:4:
parser.yy:16:10: note: forward declaration of ‘class Parametro’
In file included from /usr/include/c++/9/vector:65,
                 from parser.tab.hh:62,
                 from ./analizador/driver.h:2,
                 from lexico.l:4:
/usr/include/c++/9/bits/stl_construct.h: In instantiation of ‘void std::_Destroy(_ForwardIterator, _ForwardIterator) [with _ForwardIterator = Parametro*]’:
/usr/include/c++/9/bits/stl_construct.h:206:15:   required from ‘void std::_Destroy(_ForwardIterator, _ForwardIterator, std::allocator<_T2>&) [with _ForwardIterator = Parametro*; _Tp = Parametro]’
/usr/include/c++/9/bits/stl_vector.h:677:15:   required from ‘std::vector<_Tp, _Alloc>::~vector() [with _Tp = Parametro; _Alloc = std::allocator<Parametro>]’
parser.tab.hh:342:7:   required from ‘void yy::Parser::semantic_type::destroy() [with T = std::vector<Parametro>]’
parser.tab.hh:593:58:   required from ‘void yy::Parser::basic_symbol<Base>::clear() [with Base = yy::Parser::by_type]’
parser.tab.hh:547:9:   required from ‘yy::Parser::basic_symbol<Base>::~basic_symbol() [with Base = yy::Parser::by_type]’
parser.tab.hh:662:22:   required from here
/usr/include/c++/9/bits/stl_construct.h:133:51: error: static assertion failed: value type is destructible
  133 |       static_assert(is_destructible<_Value_type>::value,
      |                                                   ^~~~~
/usr/include/c++/9/bits/stl_construct.h:137:11: error: invalid use of incomplete type ‘std::iterator_traits<Parametro*>::value_type’ {aka ‘class Parametro’}
  136 |       std::_Destroy_aux<__has_trivial_destructor(_Value_type)>::
      |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  137 |  __destroy(__first, __last);
      |  ~~~~~~~~~^~~~~~~~~~~~~~~~~
In file included from ./analizador/driver.h:2,
                 from lexico.l:4:
parser.yy:16:10: note: forward declaration of ‘std::iterator_traits<Parametro*>::value_type’ {aka ‘class Parametro’}**strong text**

当然我在 Bison 上做错了,如果你能指导我在 Bison 产品中使用我创建的 classes,我将不胜感激。

这是我的 Bison 代码:

%skeleton "lalr1.cc" /* -*- C++ -*- */

%defines
%define api.parser.class {Parser}
%define api.token.constructor
%define api.value.type variant

%define parse.trace
%define parse.error verbose
%param { Driver& driver }


%code requires
{
   class Driver;
   class Parametro;
   class Comando;
   class Mkdisk;

}
%{
   using namespace std;
   #include <stdio.h>
   #include <iostream>
   #include <string>
   #include <vector>

   #include "driver.h"
   #include "../Clases/parametro.h"
   #include "../Clases/Comando.h"
   #include "../Comandos/Mkdisk.h"
%}


/******* TERMINALES ********/
%token GUION"GUION" IGUAL"IGUAL" 
%token <std::string> NUM"NUM" SIZE"SIZE" F"F" PATH"PATH" U"U" BF"BF" FF"FF" WF"WF" K"K" M"M" RUTA"RUTA" MKDISK"MKDISK"
%token FIN 0 "eof"

/******* NO TERMINALES ********/
%start inicio;
%type <Parametro> parametro
%type <Comando> nom_com comando
%type <std::vector<Parametro>> lista_param
%type <std::string> atributo nom_param

%%

   inicio : lista_comandos {}
          ;

   lista_comandos : lista_comandos comando  {}
                  | comando                {}
                  ;

   comando : lista_param nom_com    
               {
                  .agregarParametros();
                  $$ = ;
               }
           | nom_com                
               {
                  $$ = ;
               }
           ;

   nom_com : MKDISK     
               {
                  $$=Mkdisk();
               }
           ;
   
   lista_param : lista_param parametro    
                  {
                     $$=;
                     $$.push_back();
                  }
               | parametro                
                  {  
                     vector<Parametro> params;
                     params.push_back();
                     $$ = params;
                  }
               ;
   
   parametro : GUION nom_param IGUAL atributo { $$ = Parametro(, );}
             ;

   nom_param : SIZE     { $$=; }
             | F        { $$=; }
             | PATH     { $$=; }
             | U        { $$=; }
             ;

   atributo : NUM    { $$=; }
            | BF     { $$=; }
            | FF     { $$=; }
            | WF     { $$=; }
            | K      { $$=; }
            | M      { $$=; }
            | RUTA   { $$=; }
            ;

%%

void yy::Parser::error( const std::string& error){
  std::cout << error << std::endl;
}

我正在使用 class 驱动程序来启动解析器。有 class 驱动程序:

#include <string>
#include "parser.tab.hh"

#define YY_DECL \
    yy::Parser::symbol_type yylex (Driver& driver)
YY_DECL;

class Driver {
  public:
    void runScanner();
    void runScannerWithText(const std::string text);
    void closeFile();
    void parse(const std::string& archivo);
    void parseWithText(const std::string text);
    std::string file;
};


void Driver::parse(const std::string& archivo){
  file = archivo;

  runScanner();
  yy::Parser parser(*this);
  parser.set_debug_level(false);
  parser.parse();
  closeFile();
}

void Driver::parseWithText(std::string text){
  runScannerWithText(text);
  yy::Parser parser(*this);
  parser.set_debug_level(false);
  parser.parse();
}

此外,我还有 classes Parametro 和 Comando。 Comando 有一个参数向量。 有科曼多:



using namespace std;

#include "./parametro.h"

#include <vector>

class Comando {

    public: 
        Comando(string);
        
        string getNombre();
        vector<Parametro> getParams();

        void agregarParametros(vector<Parametro>);

    private:
        string nombre;
        vector<Parametro>params;

    protected:
        void setNombre(string);
        void setParametros(vector<Parametro>);
};


#include <vector>

Comando::Comando(string nombre){
    this->setNombre(nombre);
}

void Comando::agregarParametros(vector<Parametro>params){
    this->setParametros(params);
}


string Comando::getNombre(){
    return this->nombre;
}

vector<Parametro> Comando:: getParams(){
    return this->params;
}

void Comando::setNombre(string nombre){
    this->nombre = nombre;
}

void Comando::setParametros(vector<Parametro> params){
    this->params = params;
}

我也有一个带 flex 的词法分析器。

%{
  #include <stdio.h>
  #include <string>
  #include "driver.h"
  #include "parser.tab.hh"
%}


%option noyywrap
%option outfile="scanner.cc" 


DIGIT   [0-9]
NUM     {DIGIT}+("."{DIGIT}+)?
PATH    \"?(\/([^\/\n])*)+\"?

%%


"MKDISK"          { return yy::Parser::make_MKDISK(); }


"SIZE"            { return yy::Parser::make_SIZE(); }
"F"               { return yy::Parser::make_F(); }
"PATH"            { return yy::Parser::make_PATH(); }
"U"               { return yy::Parser::make_U(); }


{NUM}             { return yy::Parser::make_NUM();}
"BF"              { return yy::Parser::make_BF(); }
"FF"              { return yy::Parser::make_FF(); }
"WF"              { return yy::Parser::make_WF(); }
"K"               { return yy::Parser::make_K(); }
"M"               { return yy::Parser::make_M(); }
{PATH}            { return yy::Parser::make_RUTA(); }


"-"               { return yy::Parser::make_GUION(); }
"="               { return yy::Parser::make_IGUAL(); }

[[:blank:]]       {}
.                 { printf("Caracter no reconocido: %s\n",yytext);}
<<EOF>>           {return yy::Parser::make_FIN();}
%%

void Driver::runScanner(){
    yy_flex_debug = false;
    yyin = fopen (file.c_str (), "r");
    if(yyin == NULL){
        printf("No se encontro el archivo de entrada");
        exit(1);
    }
}

void Driver::runScannerWithText(std::string text){
    yy_flex_debug = true;
    YY_BUFFER_STATE buffer = yy_scan_string(text.c_str());
}

void Driver::closeFile(){
    fclose(yyin);
}

还有参数:



using namespace std;

#include <string>

class Parametro {
    public:
        Parametro(string, string);
        string getNombre();
        string getValor();

    private: 
        string valor;
        string nombre;
        void setNombre(string);
        void setValor (string);
};


using namespace std;

#include <string>
#include <vector>


#include "./parametro.h"

/*
* Parametros de cada comando. 
*/

Parametro::Parametro(string nombre, string valor){
    this->setNombre(nombre);
    this->setValor(valor);
}

void Parametro::setNombre(string nombre){
    this->nombre = nombre;
}

void Parametro::setValor(string valor){
    this->valor = valor;
}



string Parametro::getNombre(){
    return this->nombre;
}

Mkdisk 是 Comando 的儿子。就是这样:



using namespace std;

#include <string>
#include <vector>

#include "../Clases/Comando.h"

class Mkdisk : public Comando {
    
    public:
        Mkdisk();
        void agregarParametros(vector<Parametro>);

    private:
};



using namespace std;

#include <string>
#include <vector>

#include "Mkdisk.h"

Mkdisk::Mkdisk() : Comando("MKDISK"){
    printf("Creando disco");
}

void Mkdisk::agregarParametros(vector<Parametro> params){

    this->setParametros(params);

    string nombre = this->getNombre();
    
    printf("%s\n",nombre.c_str());

    printf(params[0].getNombre().c_str());
}

你们都有理由。问题是我必须对所有包含进行排序,如果您遇到此问题,请确保您正确导入了所有文件。