解析器捕获所有参数列表
Parser catch-all parameter list
好吧,我已经在这上面浪费了两天时间,并查看了与 Stack 上的 ANTLR4 有关的所有其他答案,但我无法解决这个问题。
我正在解析一个 SQL table 定义,如下所示:
CREATE TABLE [dbo].[GeographicZones](
[GeographicZoneID] [int] IDENTITY(1,1) NOT NULL,
[Township] [smallint] NOT NULL,
[Range] [smallint] NOT NULL,
[Section] [tinyint] NOT NULL,
[TownshipRange] AS ((((('T'+CONVERT([varchar](3),[Township],0))+case when [Township]>(0) then 'N' else 'S' end)+'R')+CONVERT([varchar](3),[Range],0))+case when [Range]>(0) then 'E' else 'W' end),
[LAOZone] [bit] NOT NULL,
[MSDZone] [bit] NOT NULL,
[ParrottZone] [bit] NOT NULL,
CONSTRAINT [PK_GeographicZones] PRIMARY KEY CLUSTERED
(
[GeographicZoneID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
CONSTRAINT [UK_GeographicZones_TRS] UNIQUE NONCLUSTERED
(
[Township] ASC,
[Range] ASC,
[Section] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
我无法解决的关键问题是 TownshipRange
计算列。我不关心AS
语句后()
之间的内容,想忽略直到逗号分隔符
这里是 computedColumn
规则:
/**
TSql only. In code generation, this is mapped as a read-only
property. In translation, special comments are placed that
indicate that this should be a computed column.
*/
computedColumn
: columnName AS anyExpr ( PERSISTED ( NOT NULL )? )?
{
logInfo( "Computed column {0}",
$columnName.ctx.GetText() );
}
;
这里是 anyExpr
规则,它曾经在 ANTLR4 4.0.1 中工作:
/**
Use for a parameter list (blah blah) where we don't care
about the contents. Uses a sempred to go until $open == 0.
Note that the right paren is missing from the end of the rule -
this is by design.
*/
anyExpr
locals [int open = 1]
: Lp
( {$open > 0}?
( ~( Lp | Rp )
| Lp { $open++; }
| Rp { $open--; }
)
)*
;
这是使用 ANTLR4 4.3.0 记录的输出:
INFO Computed column [TownshipRange]
line 579:22 extraneous input '(' expecting {Comma, Rp}
它失败的 (
是第一个嵌套的左括号。但是无论左括号后的第一个字符是什么,它都会立即失败并显示相同的警告。
我的 "catch-all" 逻辑有什么问题,4.0.1 和 4.3 之间有什么变化会破坏这个逻辑?
作为旁注(可能与问题有关)4.3 需要 AGES 在 LL 模式下解析整个 SQL 文件,所以我使用的是 SLL。 4.0.1 识别 LL 和 SLL 中的规则,解析时间差异很小。
4.0.1 是否可能只是忽略了无关的输入而我的 anyExpr
一直都坏了?
为什么不引用 anyExpr 本身?
anyExpr
: Lp ( ~( Lp | Rp ) | anyExpr )* Rp
;
这可能会导致更快的解析(我自己没试过!):
anyExpr
: Lp ( ~( Lp | Rp )+ | anyExpr )* Rp
;
好吧,我已经在这上面浪费了两天时间,并查看了与 Stack 上的 ANTLR4 有关的所有其他答案,但我无法解决这个问题。
我正在解析一个 SQL table 定义,如下所示:
CREATE TABLE [dbo].[GeographicZones](
[GeographicZoneID] [int] IDENTITY(1,1) NOT NULL,
[Township] [smallint] NOT NULL,
[Range] [smallint] NOT NULL,
[Section] [tinyint] NOT NULL,
[TownshipRange] AS ((((('T'+CONVERT([varchar](3),[Township],0))+case when [Township]>(0) then 'N' else 'S' end)+'R')+CONVERT([varchar](3),[Range],0))+case when [Range]>(0) then 'E' else 'W' end),
[LAOZone] [bit] NOT NULL,
[MSDZone] [bit] NOT NULL,
[ParrottZone] [bit] NOT NULL,
CONSTRAINT [PK_GeographicZones] PRIMARY KEY CLUSTERED
(
[GeographicZoneID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
CONSTRAINT [UK_GeographicZones_TRS] UNIQUE NONCLUSTERED
(
[Township] ASC,
[Range] ASC,
[Section] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
我无法解决的关键问题是 TownshipRange
计算列。我不关心AS
语句后()
之间的内容,想忽略直到逗号分隔符
这里是 computedColumn
规则:
/**
TSql only. In code generation, this is mapped as a read-only
property. In translation, special comments are placed that
indicate that this should be a computed column.
*/
computedColumn
: columnName AS anyExpr ( PERSISTED ( NOT NULL )? )?
{
logInfo( "Computed column {0}",
$columnName.ctx.GetText() );
}
;
这里是 anyExpr
规则,它曾经在 ANTLR4 4.0.1 中工作:
/**
Use for a parameter list (blah blah) where we don't care
about the contents. Uses a sempred to go until $open == 0.
Note that the right paren is missing from the end of the rule -
this is by design.
*/
anyExpr
locals [int open = 1]
: Lp
( {$open > 0}?
( ~( Lp | Rp )
| Lp { $open++; }
| Rp { $open--; }
)
)*
;
这是使用 ANTLR4 4.3.0 记录的输出:
INFO Computed column [TownshipRange]
line 579:22 extraneous input '(' expecting {Comma, Rp}
它失败的 (
是第一个嵌套的左括号。但是无论左括号后的第一个字符是什么,它都会立即失败并显示相同的警告。
我的 "catch-all" 逻辑有什么问题,4.0.1 和 4.3 之间有什么变化会破坏这个逻辑?
作为旁注(可能与问题有关)4.3 需要 AGES 在 LL 模式下解析整个 SQL 文件,所以我使用的是 SLL。 4.0.1 识别 LL 和 SLL 中的规则,解析时间差异很小。
4.0.1 是否可能只是忽略了无关的输入而我的 anyExpr
一直都坏了?
为什么不引用 anyExpr 本身?
anyExpr
: Lp ( ~( Lp | Rp ) | anyExpr )* Rp
;
这可能会导致更快的解析(我自己没试过!):
anyExpr
: Lp ( ~( Lp | Rp )+ | anyExpr )* Rp
;