我正在YACC(实际上是Bison)写一个语法,我有一个转移/减少问题.它包括后缀增量和减量运算符.这是语法的精简版:
%token NUMBER ID INC DEC
%left '+' '-'
%left '*' '/'
%right PREINC
%left POSTINC
%%
expr: NUMBER
| ID
| expr '+' expr
| expr '-' expr
| expr '*' expr
| expr '/' expr
| INC expr %prec PREINC
| DEC expr %prec PREINC
| expr INC %prec POSTINC
| expr DEC %prec POSTINC
| '(' expr ')'
;
%%
Run Code Online (Sandbox Code Playgroud)
Bison告诉我有12个移位/减少冲突,但如果我注释掉后缀增量和减量的行,它就可以正常工作.有谁知道如何解决这个冲突?在这一点上,我正在考虑转向LL(k)解析器生成器,这使得它更容易,但LALR语法似乎总是更自然地编写.我也在考虑GLR,但我不知道有什么好的C/C++ GLR解析器生成器.
我正在为MIPS架构开发一个非常简单的反编译器,随着我的进步,我必须为代码分析定义许多规则,例如"如果这个操作码是lui而下一个操作码是addiu然后返回var = value "或"如果这个操作码是bne,它指的是当前的地址 - 创建循环解析树中的定义".问题 - 有很多这样的规则,我找不到定义它们的好方法.我尝试为每个规则编写分离的函数,定义好的OOP基础逻辑类并扩展它们来创建规则,甚至尝试了令人沮丧的代码的正则表达式(令我惊讶的是这比预期更好)但无论我尝试过什么,我的代码很快变得很大,难以阅读,无论我试图记录和结构如何它.
这让我得出结论,我试图通过使用错误的工具来解决这个任务(更不用说对于这样复杂的任务来说太愚蠢:)),但我不知道应该尝试什么.目前我有两个未经考虑的想法,一个是使用某种DSL(我完全没有这方面的经验,所以我可能完全错了),另一个是编写某种类似二进制regexp的工具用于操作码匹配.
我希望有人可以指出我正确的方向,谢谢.
除了Mono和Java之外,是否有任何好的,可移植的,开源的,高级的,静态类型的,命令式的,面向对象的,垃圾收集的,安全的语言/运行时具有合理的性能?单声道很好,但它是微软的技术,我有点害怕使用它(我不确定这种恐惧是多么理性).Java的问题在于它太简单了(没有无符号数据类型,没有结构等).
这是一些简单的代码:
DIR* pd = opendir(xxxx);
struct dirent *cur;
while (cur = readdir(pd)) puts(cur->d_name);
Run Code Online (Sandbox Code Playgroud)
我得到的东西有点混乱:包括dot(.),dot-dot(..)和以~.结尾的文件名.
我想做与命令完全相同的事情ls.我该如何解决这个问题?
我想在CentOS中拖尾多个文件(并按照它们),我试过这个:
tail -f file1 file2 file3
但输出非常不友好
我也看过多头但是找不到CentOS版本.
我还有其他选择吗?
我正在用Lex和YACC创建一个编译器(实际上是Flex和Bison).该语言允许无限制地向前引用任何符号(如C#).问题是在不知道标识符是什么的情况下解析语言是不可能的.
我所知道的唯一解决方案是对整个源进行修改,然后执行"广度优先"解析,因此在使用它们的函数之前,会对类声明和函数声明等更高级别的内容进行解析.但是,这会占用大文件的大量内存,并且使用YACC很难处理(我必须为每种类型的声明/正文创建单独的语法).我也必须手写lexer(这不是一个很大的问题).
我并不关心效率(尽管它仍然很重要),因为一旦我完成它我就会重写编译器,但是我想要那个版本很快(所以如果有快速通用的话)在Lex/YACC中无法完成但可以手工完成的技术,请同时提出建议.所以现在,易于开发是最重要的因素.
这个问题有什么好的解决方案吗?这通常是如何在C#或Java等语言的编译器中完成的?
我正在设计一种高级语言,我希望它具有C++的速度(它将使用LLVM),但是像C#一样安全且高级.垃圾收集很慢,新/删除是不安全的.我决定尝试使用"基于区域的内存管理"(在网上有一些关于它的论文,主要是针对函数式语言).使用它的唯一"有用"语言是Cyclone,但也有GC.基本上,对象在词法堆栈上分配,并在块关闭时释放.对象只能引用同一区域或更高区域中的其他对象,以防止悬空引用.为了使这更加灵活,我添加了可以在堆栈中上下移动的并行区域,并通过循环保留.在大多数情况下,类型系统将能够验证分配,但在某些地方需要低开销运行时检查.
例如:
region(A) {
Foo@A x=new Foo(); //x is deleted when this region closes.
region(B,C) while(x.Y) {
Bar@B n=new Bar();
n.D=x; //OK, n is in lower region than x.
//x.D=n; would cause error: x is in higher region than n.
n.DoSomething();
Bar@C m=new Bar();
//m.D=n; would cause error: m and n are parallel.
if(m.Y)
retain(C); //On the next iteration, m is retained.
}
}
Run Code Online (Sandbox Code Playgroud)
这看起来有用吗?我是否需要添加非词法作用域,引用计数区域?我是否需要添加可以引用任何对象的弱变量,但是检查区域删除?你能想到任何难以用于这个系统或会泄漏的算法吗?
要使用OpenGL绘制复杂的凹多边形,最好将其镶嵌成三角形,还是使用模板缓冲区?我猜测单个帧的模板缓冲区会更快,但如果多边形不变,则三角测量对于多个帧会更好.但是,我还没有尝试过,所以我不知道.
我正在努力理解Continuations的概念(在Seaside with Smalltalk中使用).维基百科的一个片段说:
"...指的是一流的延续,这些结构使编程语言能够在任何时刻保存执行状态,并在程序的稍后阶段返回到该点......"
这不是表达汇编程序员编程中断时会做什么的另一种方式吗?或者我完全错过了这一点!
我知道你可以像这样在C中声明一个数组:
int nums[5] = {0,1,2,3,4};
Run Code Online (Sandbox Code Playgroud)
但是,你能这样做吗?
int nums[5];
// more code....
nums = { 0,2,5,1,2};
Run Code Online (Sandbox Code Playgroud)
换句话说,我可以在除声明之外的任何其他时间使用括号表示法初始化数组吗?谢谢你的时间,山姆