gpt4 book ai didi

vhdl - Lex VHDL '(勾号) token

转载 作者:行者123 更新时间:2023-12-02 04:04:04 25 4
gpt4 key购买 nike

在 VHDL 中,' 字符可用于封装字符标记即 '.' 或者它可以作为属性分隔符(类似于 CPP 的::标记)即 string'( “你好”)

解析包含字符即字符串'('a','b','c')的属性名称时会出现此问题。在这种情况下,天真的词法分析器会错误地将第一个 '(' 标记为字符,并且所有后续的实际字符都将被搞乱。

2007 年的 comp.lang.vhdl google 群组中有一个帖子提出了类似的问题标题为"Lexing the ' char" 用户 digratia 给出了答案

        case '\'':                          /* IR1045 check */

if ( last_token == DELIM_RIGHT_PAREN ||
last_token == DELIM_RIGHT_BRACKET ||
last_token == KEYWD_ALL ||
last_token == IDENTIFIER_TOKEN ||
last_token == STR_LIT_TOKEN ||
last_token == CHAR_LIT_TOKEN || ! (buff_ptr<BUFSIZ-2) )
token_flag = DELIM_APOSTROPHE;
else if (is_graphic_char(NEXT_CHAR) &&
line_buff[buff_ptr+2] == '\'') { CHARACTER_LITERAL:
buff_ptr+= 3; /* lead,trailing \' and char */
last_token = CHAR_LIT_TOKEN;
token_strlen = 3;
return (last_token);
}
else token_flag = DELIM_APOSTROPHE;
break;

See Issue Report IR1045: http://www.eda-twiki.org/isac/IRs-VHDL-93/IR1045.txt

As you can see from the above code fragment, the last token can be captured and used to di"sambiguate something like:

  foo <= std_logic_vector'('a','b','c');

without a large look ahead or backtracking.

但是,据我所知,flex 不会跟踪最后解析的标记。

无需手动跟踪最后解析的标记,是否有更好的方法来完成此词法分析任务?

如果有帮助的话,我正在使用 IntelliJ GrammarKit。

最佳答案

IR1045 背后的想法是能够判断单引号/撇号是否是字 rune 字的一部分,而无需向前看或在错误时回溯,尝试:

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 的撇号和字 rune 字进行灵活消歧的实际示例。

Nick Gasson 的 nvc 使用 flex,他在其中实现了问题报告 1045 解决方案。

请参阅nvc/src/lexer.l根据 GPLv3 获得许可。

搜索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 使用该函数来过滤检测字 rune 字的第一个单引号。

这最初是 Ada 问题。 IR-1045 从未被采用,但得到普遍使用。可能有 Ada flex 词法分析器也可以演示消歧功能。

Ada 用户日志卷 27 number 3 中讨论了消除歧义的要求。从 2006 年 9 月起,在 PDF 第 30 和 31 页(第 27 卷第 159 和 160 页)上的一篇文章词法分析中,我们看到解决方案并不为人所知。

关于字 rune 字不在单引号之前的注释是不准确的:

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;

第一次使用具有选定名称前缀的属性,该属性的后缀是字 rune 字,这表明了不准确性,第二个报告语句表明它可能很重要:

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

除了包含带有字 rune 字后缀的选定名称的属性名称前缀之外,还要求属性规范以相同的方式“装饰”声明的实体(实体类的实体,请参阅 IEEE Std 1076-2008 7.2 属性规范)声明实体的声明区域。

此示例在语法和语义上都是有效的 VHDL。您可能会注意到,nvc 不允许使用实体类文字来装饰命名实体。这不符合 7.2 的规定。

枚举文字在类型声明中声明,此处类型为twovalue。至少有一个字 rune 字作为枚举文字的枚举类型是字符类型 (5.2.2.1)。

关于vhdl - Lex VHDL '(勾号) token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43159960/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com