前言
PHP使用的词法分析使用的是Bison,它是将LALR(1)上下文无关语法描述转换为C语言的语法解析器。
语法分析说明
%{
定义头
%}
%token头定义
%%
语法格式
%%
C语言代码
语法分析实例
先看下bison的示例:计算器
calc.l(词法解析格式)
%{
# include "y.tab.h"
int lexerror(char *s);
%}
%%
"+" { return ADD; }
"-" { return SUB; }
"*" { return MUL; }
"/" { return DIV; }
"(" { return LP; }
")" { return RP; }
[0-9]+ { yylval = atoi(yytext); return NUM; }
\n { return EOL; }
[ \t] { /* ignore white space */ }
. { lexerror(yytext); }
%%
int lexerror(char *s)
{
fprintf(stderr, "lexical error: %s\n", s);
}
calc.y(语法解析格式)
%{
# include <stdio.h>
int yyerror(char *s);
int yylex();
%}
//set attribute type
%define api.value.type {int}
/* declare tokens (terminal symbols) */
%token NUM 256
%token ADD 257
%token SUB 258
%token MUL 259
%token DIV 260
%token LP 261
%token RP 262
%token EOL 263
%%
start:
| start expr EOL { printf("= %d\n> ", $2); };
expr: term
| expr ADD term { $$ = $1 + $3; }
| expr SUB term { $$ = $1 - $3; }
;
term: factor { $$ = $1; }
| term MUL factor { $$ = $1 * $3; }
| term DIV factor { $$ = $1 / $3; }
;
factor: NUM { $$ = $1; }
| LP expr RP { $$ = $2; }
;
%%
int main()
{
printf("> ");
yyparse();
}
int yyerror(char *s)
{
fprintf(stderr, "error: %s\n", s);
}
makefile
OUT = calc
CC = gcc
SCANNER = calc.l
PARSER = calc.y
OBJ = y.tab.o lex.yy.o
OUTFILES = lex.yy.c y.tab.c y.tab.h y.output $(OUT)
build: $(OUT)
clean:
rm -f *.o $(OUTFILES)
lex.yy.c: $(SCANNER) y.tab.c
flex $<
y.tab.c: $(PARSER)
bison -vdty $<
y.tab.o: y.tab.c
$(CC) -c $<
lex.yy.o: lex.yy.c
$(CC) -c $<
$(OUT): $(OBJ)
$(CC) -o $(OUT) $(OBJ) -lfl
运行结果
root@39b93c626114:/opt/app/calc# ./calc
> 1+1
=2
>1+1-3
=-1
>1+6*7-8
=35
>