2017-04-01 9 views
4

VHDL에서는'문자를 사용하여 문자 토큰 ie '.'을 캡슐화하거나 특성 구분 기호 (CPP의 토큰과 비슷 함) ie string'("hello")을 사용할 수 있습니다.VHDL '(tick) 토큰 Lexing

ie string'('a','b','c') 문자가 포함 된 속성 이름을 구문 분석 할 때 문제가 발생합니다. 이 경우 순수한 렉서가 처음으로 '('을 문자로 토큰 화하고 다음 실제 문자가 모두 엉망이됩니다. 사용자 diogratia의 답변을 가지고 "Lexing the ' char"

 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; 

참조 문제 보고서 IR1045라는 비슷한 질문 을 요청 2007 comp.lang.vhdl 구글 그룹의 스레드가 있습니다

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

위의 코드 조각에서 알 수 있듯이 마지막 토큰은 일 수 있으며 "somecin 좋아요 :

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

미리보기 또는 되돌아 가기가 없습니다.

그러나 필자가 아는 한 flex는 마지막으로 구문 분석 된 토큰을 추적하지 않습니다.

수동으로 마지막 구문 분석 된 토큰을 추적하지 않아도이 렉싱 작업을 수행하는 더 좋은 방법이 있습니까?

도움이된다면 IntelliJ GrammarKit을 사용하고 있습니다.

답변

5
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를 사용하여 이슈 보고서 1045 솔루션을 구현했습니다.

nvc/src/lexer.l (GPLv3으로 라이센스가 있음)을 참조하십시오. last_token위한

검색 :

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; 
    } 
} 
,536,913,632

#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)); 

그것을 확인하는 기능을 추가 10

comp.lang 이후 IR1045 위치가 변경되었습니다.VHDL 게시물 지금

또한 lexer.l에서 resolve_ir1045 검색 할 수 있습니다 http://www.eda-twiki.org/isac/IRs-VHDL-93/IR1045.txt

입니다. 우리가 NVC를 찾을

{CHAR}   { if (resolve_ir1045()) { 
         yylval.s = strdup(yytext); 
         TOKEN(tID); 

static int resolve_ir1045(void); 

리터럴 문자의 첫 번째 작은 따옴표를 검출하는 필터링 기능을 사용합니다.

이것은 원래 Ada 문제였습니다. IR-1045는 결코 채택되지 않았지만 보편적으로 사용되었습니다. 어쩌면 애매 모호성을 나타내는 Ada flex 렉서가있을 수 있습니다.

명확하게 할 필요

우리가 솔루션은 잘 알려져 있지 않다 참조 PDF 페이지 30, 31 (권 27 페이지 159 및 160)에 기사 어휘 분석 년 9 월 2006 년 에이다 사용자 저널 볼륨 27 number 3에서 설명합니다.

해당 문자 리터럴은 작은 따옴표 앞에하지 않는 의견은 정확 :

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 

문자 리터럴 접미사가 있으면 속성 선언은 엔티티가 선언 된 동일한 선언적 영역에서 선언 된 엔티티 (entity_class의 IEEE Std 1076-2008 7.2 속성 사양 참조)를 '장식'해야합니다.

이 예는 다음과 같습니다. 구문 적으로 의미 론적으로 유효한 VHDL. nvc는 엔티티 클래스 리터럴을 사용하여 명명 된 엔티티를 꾸밀 수 없습니다. 그것은 7.2에 따르지 않습니다.

열거 형 리터럴은 형식 선언에 선언되어 있습니다. 여기에는 유형 2가 있습니다. 열거 형은 적어도 하나의 문자 리터럴을 열거 형 리터럴로 가지는 문자 유형 (5.2.2.1)입니다.

+0

왜 이러한 문제는 2000 년대에 나타 났지만 문자 기능 대 문자 유형 자격 대 한 문자 이름의 속성은 훨씬 오래 되었습니까? 지금까지 내가 아는 한, 대부분의 VHDL 파서는 손으로 쓴 것이며 파서/렉서 제너레이터에 의존하지 않는다. 대부분의 경우 VHDL의 특수한 경우를 회피하기 위해 많은 특별한 규칙을 작성하게됩니다. – Paebbels

+0

한 손으로 1991 년경부터 처음부터 시작되어 여전히 손가락이 남아있는 상용 VHDL 구현의 수를 계산할 수 있습니다. 일반적으로 사물을 찾지 못하고 아무도 문서에 빵 부스러기를 남기지 않는 모험담입니다. 나는 그것이 제로 합계 경쟁이라고 생각 했었습니다. 누군가가 시장 점유율을 잃어 다른 사람이 시장 점유율을 확보해야만 도움을 줄 수 있습니다. 요즘 예술의 상태는 다중 언어 시뮬레이션 및 합성입니다. 어쨌든 시작은 경쟁 할 수 없으며, 그 분야는 특허가 풍부합니다. – user1155120

+0

@Paebbels Ada도 같은 방식입니다. Ada 컴파일러가 마지막으로 언제 있었습니까? – user1155120