lemon.c 和lempar.c 下载地址 :http://www.hwaci.com/sw/lemon/ 或者 sqlite官网 。
lemon 默认生成的是C文件 ,但是只需要修改一下便可以生成C++代码 。
找到lemon.c 文件中的 file_open()函数,其中有一个的调用参数传值的是".c" ,将其修改为".cpp" 即可生成C++文件 。语法文件编译生成的.cpp文件在运行的时候会报找不到标识符 NEVER 。我找了下lemon.c 和lempar.c 文件,均没有这个标识符 ,暂时我也无法解释为什么会多出来这么个东西,观察这个NEVER出现的地方,发现一个解决方法 ,就是在你的语法分析文件的%include部分自己添加一个NEVER函数 。
形如 :
bool NEVER(bool x)
{
return x== 1?1 :0 ;
}
只要能达到缺少的标识符地方的效果就行,至于怎么处理,可以多样化,此处只是举个例子而已。
不知道为什么生成的.c文件使用ParseTrace()函数跟踪会报错 【由于报错显示的都是.y文件,且没有具体提示在哪一行,因此我也没有解决这个问题。】。但是使用生成的.cpp文件不会有这个问题 。
贴个测试过的小例子 :
%include {
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include "example4.h"
typedef struct Token{
int values ;
unsigned int n ;
}Token;
bool NEVER (bool x)
{
return x==1 ? 1 :0;
}
}
%token_type {Token}
%default_type {Token}
%left PLUS MINUS.
%left DIVIDE TIMES.
%syntax_error {
printf("syntax error!\n");
}
program ::=expr(A).{
printf("Result.values = %d\n",A.values);
printf("Result.n = %d \n",A.n);
}
expr(A) ::= expr(B) PLUS expr(C).{
A.values = B.values + C.values ;
A.n = B.n +1 + C.n +1 ;
}
expr(A) ::= expr(B) MINUS expr(C).{
A.values = B.values - C.values ;
A.n = B.n +1 + C.n +1 ;
}
expr(A) ::= expr(B) TIMES expr(C).{
A.values = B.values * C.values ;
A.n = B.n +1 + C.n +1 ;
}
expr(A) ::= expr(B) DIVIDE expr(C).{
if(C.values !=0 )
A.values = B.values / C.values ;
else {
printf("divide by zero!\n");
}
A.n = B.n +1 + C.n +1 ;
}
expr(A) ::=NUM(B). {
A.values = B.values ;
A.n = B.n + 1 ;
}
%code {
int main()
{
FILE *f;
f = fopen("record.txt","w");
ParseTrace(f,"");
void * pParser = ParseAlloc(malloc);
Token t0 ,t1 ;
t0.values = 4 ;
t0.n = 0 ;
t1.values = 13 ;
t1.n = 0 ;
printf("\t t0.values(4) PLUS t1.values(13) \n");
Parse(pParser,NUM,t0);
Parse(pParser,PLUS,t0);
Parse(pParser,NUM,t1);
Parse(pParser,0,t0);
printf("\t t0.values(4) MINUS t1.values(13) \n");
Parse(pParser,NUM,t0);
Parse(pParser,MINUS,t0);
Parse(pParser,NUM,t1);
Parse(pParser,0,t0);
printf("\t t0.values(4) TIMES t1.values(13) PLUS t1.values(13) PLUS t1.values(13) \n");
Parse(pParser,NUM,t0);
Parse(pParser,TIMES,t0);
Parse(pParser,NUM,t1);
Parse(pParser,PLUS,t0);
Parse(pParser,NUM,t1);
Parse(pParser,PLUS,t0);
Parse(pParser,NUM,t1);
Parse(pParser,0,t0);
ParseFree(pParser,free);
ParseTrace(NULL,"");
int flag = fclose(f);
}
}
希望能帮到需要的人!