我试图使用Flex和Bison与C ++创建简单的编译器,但我无法理解为什么当Flex到达文件末尾时,它会将C ++文件中声明的变量重置为其初始值。 / p> lex.l 文件中的
:
final WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN ,
PixelFormat.TRANSLUCENT);
myView = (ViewGroup) LayoutInflater.from(context.getApplicationContext()).inflate(R.layout.sample, null);
myView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
wm.addView(myView,params); //I have set some params upper
和 HelperCode.h 文件:
%{
#include "HelperCode.h"
// ... etc
%}
%option c++
%option noyywrap
%option yylineno
%%
[\n] { dosomething();}
// ...etc
%%
并在 yacc.y 文件中:
namespace
{
int counter = 0;
//rest of code
void dosomething()
{
counter++;
cout << counter << " ";
// here it will print the correct values based on input
// ex: 1 2 3 4 5
}
void afterfinish()
{
cout << endl << counter;
// but here it will print '0', like if the counter reset to 0
}
}
答案 0 :(得分:4)
问题几乎可以肯定是您将namespace { ... }
放入头文件中。
包含此文件的每个C ++翻译单元都会获得头文件原始文本的副本,因此具有名称空间声明的副本。由于命名空间是匿名的,因此每个副本都是独立的;包含此的每个翻译单元都有自己的 counter
,以及dosomething
和afterfinish
。
这与C语言中将一些静态定义放入标题的情况非常相似,如下所示:
static int counter = 0;
static void dosomething(void) { printf("%d\n", ++counter); }
static void afterfinish(void) { printf("%d\n", counter); }
每个C单元#include
- 此标头都有自己的计数器,以及对其进行操作的一对私有函数dosomething
和afterfinish
。
词法分析器模块在其自己的计数器上运行,包含afterfinish
的模块中的main
在其自己的计数器上运行,该计数器仍为零。
如果你想要一个模块共享的命名空间,只需给它一个名字。
// header file HelperCode.h
namespace parser_stuff {
// We no longer *define* the counter in the header, just declare it.
extern int counter;
// And we use inline on functions defined in the header, otherwise
// they will now be multiply defined!
inline void dosomething()
{
counter++;
// ... etc
}
// non-inline function
void afterfinish();
}
// In one .cpp file somewhere, perhaps HelperCode.cpp
#include "HelperCode.h"
namespace parser_stuff {
int counter = 0; // One program-wide definition of parser_stuff::counter.
void afterfinish()
{
// ....
}
}
当然,我们现在必须做
%{
#include "HelperCode.h"
// ... etc
%}
%option c++
%option noyywrap
%option yylineno
%%
[\n] { parser_stuff::dosomething();}
// ...etc
%%
否则:
%{
#include "HelperCode.h"
// ... etc
// one of these: bring in a specific identifier, or whole namespace:
using parser_stuff::dosomething;
using namespace parser_stuff;
%}
%option c++
%option noyywrap
%option yylineno
%%
[\n] { dosomething();}
// ...etc
%%
,类似地在主模块中引用afterfinish
。