Sqlite3之Lemon语法解析器初探(1)
添加时间:2013-5-26 点击量:
转载请注明出处
看sqlite3源码发明用到了lemon语法解析器 ,然后发明一本好的lemon教程 然后参考里面的例子 做了一些例子。
Lemon语法解析器 很是小巧 只依附于两个文件 。
以下的代码实现一个策画器法度。初步的没有参加词法生成器,直接调用了Parse函数来做运算。代码中包含注释,以下并申明具体点。
//在生成的文件中包含以下头文件
%include
{
????#include<stdio.h>
????#include calculator-bak2.h
????#include<malloc.h>
????#include<assert.h>
}
//策画器里面类型都是整形
%token_type{int}
//策画符连络办法都是左连络的办法
//之所以分隔写是因为 下面的运算符级别高于上方的 这里是乘除高于加减
%left PLUS MINUS.
%left DIVIDE TIMES.
?
%syntax_error
{
????printf(语法解析错误,不法的表达式了 \n);
????//本身的处理惩罚代码
}
//意思就是expr定义为一个公式
program ::=expr(A).
{
printf(this %d /n,A);
}
?
expr(A) ::=expr(B) MINUS expr(C).{A=B-C;}
expr(A) ::=expr(B) PLUS expr(C).{A=B+C;}
expr(A) ::=expr(B) TIMES expr(C).{A=BC;}
expr(A) ::=expr(B) DIVIDE expr(C).{
A=B/C;
}
//这里可以看到 expr到底是什么了????
expr(A) ::= INTEGER(B). {A=B;}
?
//lemon 的两种符号 终结符 与非终结符
//终结符来自外面 大写 非终结符来自内部 小写
?
%code
{
void main()
{
void pParser = ParseAlloc(malloc);
Parse(pParser,INTEGER,1);
Parse(pParser,PLUS,0);
Parse(pParser,INTEGER,2);
Parse(pParser,0,0);
ParseFree(pParser,free);
}
}
?
解析main函数里面代码的履行步调 expr(A) ::= INTEGER(B). {A=B;} expr(A) ::=expr(B) PLUS expr(C).{A=B+C;} program ::=expr(A).
里面先后履行了这几个步调
INTEGER(1) > expr(1)
PLUS(0)
INTEGER(2) > expr(2)
expr(1)PLUS(0)expr(2) 匹配到了 A=B+C expr(3)被放到解析stack中 然后调用了 printf那个语句
终极打印出来 this 3
接下改变 main()函数里面code 然后+-乘除混淆运算
void pParser = ParseAlloc(malloc);
Parse(pParser,INTEGER,1);
Parse(pParser,PLUS,0);
Parse(pParser,INTEGER,2);
Parse(pParser,TIMES,1);
Parse(pParser,INTEGER,5);
Parse(pParser,0,0);
ParseFree(pParser,free);
打印成果 this 11 申明是混淆运算
?
可以用布局体调换 INTEGER来进行错杂运算 这里不做赘述
?
?
?
????
?
?
?
?
?
我俩之间有着强烈的吸引力。短短几个小时后,我俩已经明白:我们的心是一个整体的两半,我俩的心灵是孪生兄妹,是知己。她让我感到更有活力,更完美,更幸福。即使她不在我身边,我依然还是感到幸福,因为她总是以这样或者那样的方式出现在我心头。——恩里克·巴里奥斯《爱的文明》
转载请注明出处
看sqlite3源码发明用到了lemon语法解析器 ,然后发明一本好的lemon教程 然后参考里面的例子 做了一些例子。
Lemon语法解析器 很是小巧 只依附于两个文件 。
以下的代码实现一个策画器法度。初步的没有参加词法生成器,直接调用了Parse函数来做运算。代码中包含注释,以下并申明具体点。
//在生成的文件中包含以下头文件
%include
{
????#include<stdio.h>
????#include calculator-bak2.h
????#include<malloc.h>
????#include<assert.h>
}
//策画器里面类型都是整形
%token_type{int}
//策画符连络办法都是左连络的办法
//之所以分隔写是因为 下面的运算符级别高于上方的 这里是乘除高于加减
%left PLUS MINUS.
%left DIVIDE TIMES.
?
%syntax_error
{
????printf(语法解析错误,不法的表达式了 \n);
????//本身的处理惩罚代码
}
//意思就是expr定义为一个公式
program ::=expr(A).
{
printf(this %d /n,A);
}
?
expr(A) ::=expr(B) MINUS expr(C).{A=B-C;}
expr(A) ::=expr(B) PLUS expr(C).{A=B+C;}
expr(A) ::=expr(B) TIMES expr(C).{A=BC;}
expr(A) ::=expr(B) DIVIDE expr(C).{
A=B/C;
}
//这里可以看到 expr到底是什么了????
expr(A) ::= INTEGER(B). {A=B;}
?
//lemon 的两种符号 终结符 与非终结符
//终结符来自外面 大写 非终结符来自内部 小写
?
%code
{
void main()
{
void pParser = ParseAlloc(malloc);
Parse(pParser,INTEGER,1);
Parse(pParser,PLUS,0);
Parse(pParser,INTEGER,2);
Parse(pParser,0,0);
ParseFree(pParser,free);
}
}
?
解析main函数里面代码的履行步调 expr(A) ::= INTEGER(B). {A=B;} expr(A) ::=expr(B) PLUS expr(C).{A=B+C;} program ::=expr(A).
里面先后履行了这几个步调
INTEGER(1) > expr(1)
PLUS(0)
INTEGER(2) > expr(2)
expr(1)PLUS(0)expr(2) 匹配到了 A=B+C expr(3)被放到解析stack中 然后调用了 printf那个语句
终极打印出来 this 3
接下改变 main()函数里面code 然后+-乘除混淆运算
void pParser = ParseAlloc(malloc);
Parse(pParser,INTEGER,1);
Parse(pParser,PLUS,0);
Parse(pParser,INTEGER,2);
Parse(pParser,TIMES,1);
Parse(pParser,INTEGER,5);
Parse(pParser,0,0);
ParseFree(pParser,free);
打印成果 this 11 申明是混淆运算
?
可以用布局体调换 INTEGER来进行错杂运算 这里不做赘述
?
?
?
????
?
?
?
?
?