IR1045 背后的想法是能够判断单引号/撇号是否是字符文字的一部分,而无需向前看或在错误时回溯,请尝试:
library ieee;
use ieee.std_logic_1164.all;
entity foo is
port (
a: in std_logic;
b: out std_logic_vector (3 downto 0)
);
end entity;
architecture behave of foo is
begin
b <= std_logic_vector'('0','1','1','0') when a = '1' else
(others =>'0') when a = '0' else
(others => 'X');
end architecture behave;
你愿意向前看多远?
然而,有一个用于 VHDL 的撇号和字符文字的灵活消歧的实际示例。
Nick Gasson 的 nvc 使用 flex,他在其中实施了 Issue Report 1045 解决方案。
请参阅根据 GPLv3 许可的nvc/src/lexer.l 。
搜索 last_token:
#define TOKEN(t) return (last_token = (t))
和
#define TOKEN_LRM(t, lrm) \
if (standard() < lrm) { \
warn_at(&yylloc, "%s is a reserved word in VHDL-%s", \
yytext, standard_text(lrm)); \
return parse_id(yytext); \
} \
else \
return (last_token = (t));
一个附加的功能来检查它:
static int resolve_ir1045(void);
static int last_token = -1;
这是:
%%
static int resolve_ir1045(void)
{
// See here for discussion:
// http://www.eda-stds.org/isac/IRs-VHDL-93/IR1045.txt
// The set of tokens that may precede a character literal is
// disjoint from that which may precede a single tick token.
switch (last_token) {
case tRSQUARE:
case tRPAREN:
case tALL:
case tID:
// Cannot be a character literal
return 0;
default:
return 1;
}
}
自 comp.lang.vhdl 发布以来,IR1045 位置已更改
http://www.eda-twiki.org/isac/IRs-VHDL-93/IR1045.txt
您还需要在 lexer.l 中搜索 resolve_ir1045。
static int resolve_ir1045(void);
和
{CHAR} { if (resolve_ir1045()) {
yylval.s = strdup(yytext);
TOKEN(tID);
我们发现 nvc 使用该函数来过滤检测字符文字的第一个单引号。
这最初是一个 Ada 问题。IR-1045 从未被采用,但被普遍使用。可能有 Ada flex 词法分析器也证明了歧义。
Ada User Journal 第27 卷第 3期自 2006 年 9 月的一篇文章Lexical Analysis on PDF 第 30 页和第 31 页(第 27 卷第 159 和 160 页)中讨论了消除歧义的要求,我们发现解决方案并不为人所知。
字符文字不在单引号之前的注释是不准确的:
entity ir1045 is
end entity;
architecture foo of ir1045 is
begin
THIS_PROCESS:
process
type twovalue is ('0', '1');
subtype string4 is string(1 to 4);
attribute a: string4;
attribute a of '1' : literal is "TRUE";
begin
assert THIS_PROCESS.'1''a /= "TRUE"
report "'1''a /= ""TRUE"" is FALSE";
report "This_PROCESS.'1''a'RIGHT = " &
integer'image(This_PROCESS.'1''a'RIGHT);
wait;
end process;
end architecture;
第一次使用具有选定名称前缀且后缀为字符文字的属性证明了不准确,第二个报告语句表明它可能很重要:
ghdl -a ir1045.vhdl
ghdl -e ir1045
ghdl -r ir1045
ir1045.vhdl:13:9:@0ms:(assertion error): '1''a /= "TRUE" is FALSE
ir1045.vhdl:15:9:@0ms:(report note): This_PROCESS.'1''a'RIGHT = 4
除了包含带有字符文字后缀的选定名称的属性名称前缀之外,还要求属性规范“装饰”同一声明区域中的声明实体(实体类的,请参见 IEEE Std 1076-2008 7.2 属性规范)实体在中声明。
这个例子在句法和语义上都是有效的 VHDL。您可能会注意到 nvc 不允许使用实体类文字装饰命名实体。这不是根据 7.2。
枚举字面量在类型声明中声明,这里类型为 twovalue。具有至少一个字符文字作为枚举文字的枚举类型是字符类型 (5.2.2.1)。