Postgresql源码(98)lex与yacc的定制交互方式
创始人
2024-05-12 17:17:55
0

1 背景知识一:LEX %option prefix

Postgresql中使用%option prefix="core_yy",影响范围:yy_create_buffer,yy_delete_buffer,yy_flex_debug,yy_init_buffer,yy_flush_buffer,yy_load_buffer_state,yy_switch_to_buffer,yyin,yyleng,yylex,yylineno,yyout,yyrestart,yytext,yywrap,yyalloc,yyrealloc,yyfree。

所以lex提供的yylex在PG中是core_yylex。

‘-PPREFIX, --prefix=PREFIX, %option prefix="PREFIX"’
changes the default ‘yy’ prefix used by flex for all globally-visible variable and function names to instead be ‘PREFIX’. For example, ‘--prefix=foo’ changes the name of yytext to footext. It also changes the name of the default output file from lex.yy.c to lex.foo.c. Here is a partial list of the names affected:yy_create_bufferyy_delete_bufferyy_flex_debugyy_init_bufferyy_flush_bufferyy_load_buffer_stateyy_switch_to_bufferyyinyylengyylexyylinenoyyoutyyrestartyytextyywrapyyallocyyreallocyyfree
(If you are using a C++ scanner, then only yywrap and yyFlexLexer are affected.) Within your scanner itself, you can still refer to the global variables and functions using either version of their name; but externally, they have the modified name.This option lets you easily link together multiple flex programs into the same executable. Note, though, that using this option also renames yywrap(), so you now must either provide your own (appropriately-named) version of the routine for your scanner, or use %option noyywrap, as linking with ‘-lfl’ no longer provides one for you by default.

https://www.cs.virginia.edu/~cr4bd/flex-manual/Code_002dLevel-And-API-Options.html#Code_002dLevel-And-API-Options

2 背景知识二:YACC %name-prefix

lex and yacc中可以使用prefix指定内置函数、变量的前缀,实现一套代码中包含多套解析器。

Postgresql中使用%name-prefix="base_yy",影响范围:yyparse, yylex, yyerror, yynerrs, yylval, yylloc, yychar and yydebug。

所以yacc中调用的yylex函数实际是base_yylex。

但是lex提供的是core_yylex,yacc调用的是base_yylex,怎么找到core_yylex呢?看下一节。

The renamed symbols include yyparse, yylex, yyerror, yynerrs, yylval, yylloc, yychar and yydebug. If you use a push parser, yypush_parse, yypull_parse, yypstate, yypstate_new and yypstate_delete will also be renamed. The renamed macros include YYSTYPE, YYLTYPE, and YYDEBUG, which is treated specifically — more about this below.

https://www.gnu.org/software/bison/manual/bison.html#Multiple-Parsers

3 yylex与yyparse

  • yyparse是yacc入口,pg中在raw_parser中调用。
  • yylex是lex入口,yacc通过自定义base_yylex函数,在函数中调用core_yylex进入lex拿token和值。

3.1 yylex和yyparse的参数

首先关注在gram.y中的几个重要配置:

gram.y%pure-parser
%name-prefix="base_yy"
%locations%parse-param {core_yyscan_t yyscanner}
%lex-param   {core_yyscan_t yyscanner}

参数配置函数:

参数影响yylexyyparse
初始形态的yylex函数int yylex()int yyparse ()
加parse-param后int yylex(core_yyscan_t yyscanner)int yyparse (core_yyscan_t yyscanner)
加pure-parser后int yylex(YYSTYPE *lvalp, core_yyscan_t yyscanner)int yyparse (core_yyscan_t yyscanner)
加locations后int yylex(YYSTYPE *lvalp, YYLTYPE *llocp, core_yyscan_t yyscanner)int yyparse (core_yyscan_t yyscanner)

YYSTYPE是什么:token的值保存在全局变量yylval中,yylval的类型是YYSTYPE。
YYLTYPE是什么:token的位置保存在全局变量yylloc中,yylloc的类型是YYLTYPE。

YYSTYPE会在gram.y中编译为联合体YYSTYPE,其中第一个子类型就是core_YYSTYPE core_yystype;

union YYSTYPE
{
#line 230 "gram.y"core_YYSTYPE core_yystype;/* these fields must match core_YYSTYPE: */int			ival;char	   *str;const char *keyword;char		chr;bool		boolean;
...
...
#line 604 "gram.h"};

3.2 yyparse与base_yylex的调用流程

在这里插入图片描述

base_yylex(YYSTYPE *lvalp, YYLTYPE *llocp, core_yyscan_t yyscanner)...cur_token = core_yylex(&(lvalp->core_yystype), llocp, yyscanner);...

其中lvalp和lvalp->core_yystype地址相同,因为是一个联合体:
在这里插入图片描述

相关内容

热门资讯

保存时出现了1个错误,导致这篇... 当保存文章时出现错误时,可以通过以下步骤解决问题:查看错误信息:查看错误提示信息可以帮助我们了解具体...
汇川伺服电机位置控制模式参数配... 1. 基本控制参数设置 1)设置位置控制模式   2)绝对值位置线性模...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
本地主机上的图像未显示 问题描述:在本地主机上显示图像时,图像未能正常显示。解决方法:以下是一些可能的解决方法,具体取决于问...
不一致的条件格式 要解决不一致的条件格式问题,可以按照以下步骤进行:确定条件格式的规则:首先,需要明确条件格式的规则是...
表格列调整大小出现问题 问题描述:表格列调整大小出现问题,无法正常调整列宽。解决方法:检查表格的布局方式是否正确。确保表格使...
表格中数据未显示 当表格中的数据未显示时,可能是由于以下几个原因导致的:HTML代码问题:检查表格的HTML代码是否正...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...