PostgreSQL source code interpretation (167)-query # 87 (basics-parser Bison)
Enter a SQL statement, how does PostgreSQL parse the input SQL and identify the SQL type and base table / field information? The next few sections will be analyzed one by one.
This section introduces the open source tool parser Bison.
1. Bison
Basic concept
Bison is a parser that works with Flex to convert user-provided syntax rules into a parser. Flex generates token stream,Bison to parse the token stream according to the defined production and action tables, thus parsing sentences.
Bison custom syntax files, usually with a .y file extension, are in the following format:
% {Declarations%} Definitions%%Productions%%User subroutines
The Declarations (declaration) and User subroutines (user-defined process) are the same as the Flex .l file, and Bison will copy the code to the y.tab.c file as is; the Definitions (definition) section, like Flex, defines some Bison-specific variables in this section and explains the code in this section later; the most important is the Productions section, which is syntax production written by the user.
Example
Let's use Flex and Bison to implement a simple multiplier.
Mul.l
Lexical file
% {# include "y.tab.h" void yyerror (const char * msg); void undefined_char (char c);%}% [0-9] + {yylval = atoi (yytext); return token number;} [* ()\ n] {return yytext [0];}. {return 0; / * end when meet everything else * /}% int yywrap (void) {return 1;} void undefined_char (char c) {char buf [32] = "Unrecognized character:?"; buf [24] = c; yyerror (buf);} void yyerror (const char * msg) {printf ("Error:% s\ n", msg); exit (1);}
Mul.y
Grammar file
% {# include%}% token T_NUMBER%left'*% S: s'\ n' {printf ("result =% d\ n", $2);} | / * empty * / {/ * empty * /}; E: e'* E {$= $1 * $3;} | T_NUMBER {$$= $1;};% int main () {return yyparse ();}
Makefile
CC = gccOUT = mulOBJ = lex.yy.o y.tab.oMUL_L = mul.lMUL_Y = mul.ybuild: $(OUT) run: $(OUT). / $(OUT) clean: rm-f * .o lex.yy.c y.tab.c y.tab.h y.output $(OUT) $(OUT): $(OBJ) $(CC)-o $(OUT) $(OBJ) lex.yy.c: $(MUL_L) y.tab.c flex $