2013-07-25 2 views
2

Ragel이 "최종"상태로 간주하는 것을 이해하지 못합니다. IIRC 사용자 안내서는 기계 단순화 이전에 최종 상태로 남아있는 상태가 남아 있다고 말합니다. 정확히 final 인 상태이며이를 어떻게 인식합니까?Ragel, 최종 상태 및 EOF


응용 프로그램 : 내가 문자열 찾기를 구현하는 상태 머신 구문을 사용하고

- n보다 더 큰 길이 ASCII 문자열을 발견하고 그것들을 인쇄 할 수 있습니다. 이것은 아래와 같이 최대 길이 매처를 구현하는 것을 의미합니다.

도트 출력이 최종 상태를 나타내지 않지만 EOF 전환은 {$%@}eof의 어떤 맛이 사용되는지에 따라 다르게 동작합니다. 나는 이것이 왜 있어야하는지 이해하지 못합니다. 예를 들어 아래의 has_string 상태에서 @eof 대신 %eof을 사용하면 일치 상태를 종료하는 생성/합성 상태 중 하나에서 commit_nonstring_eofcommit_string_eof 작업이 모두 호출됩니다.

여기는 작동하는 상태 기계입니다. 맨 오른쪽 노드 종료 작업에는 정확히 하나의 작업, 즉 commit_nonstring_eof이 있습니다. Working state machine

여기는 고장난 상태 시스템입니다. 맨 오른쪽 노드 종료 조치를 호출합니다 모두 commit_string_eofcommit_nonstring_eof Bad state machine

action commit_string { } 
action commit_string_eof { } 
action commit_nonstring_eof { } 
action set_mark { } 

action reset { 
    /* Force the machine back into state 1. This happens after 
    * an incomplete match when some graphical characters are 
    * consumed, but not enough for use to keep the string. */ 
    fgoto start; 
} 

# Matching classes union to 0x00 .. 0xFF 
graphic = (0x09 | 0x20 .. 0x7E); 
non_graphic = (0x00 .. 0x08 | 0x0A .. 0x1F | 0x7F .. 0xFF); 

collector = (

start: (
    # Set the mark if we have a graphic character, 
    # otherwise go to non_graphic state and consume input 
    graphic @set_mark -> has_glyph | 
    non_graphic -> no_glyph 
) $eof(commit_nonstring_eof), 

no_glyph: (
    # Consume input until a graphic character is encountered 
    non_graphic -> no_glyph | 
    graphic @set_mark -> has_glyph 
) $eof(commit_nonstring_eof), 

has_glyph: (
     # We already matched one graphic character to get here 
     # from start or no_glyph. Try to match N-1 before allowing 
     # the string to be committed. If we don't get to N-1, 
     # drop back to the start state 
     graphic{3} $lerr(reset) -> has_string 
) @eof(commit_nonstring_eof), 

    has_string: (
     # Already consumed our quota of N graphic characters; 
     # consume input until we run out of graphic characters 
     # then reset the machine. All exiting edges should commit 
     # the string. We differentiate between exiting on a non-graphic 
     # input that shouldn't be added to the string and exiting 
     # on a (graphic) EOF that should be added. 
     graphic* non_graphic -> start 
) %from(commit_string) @eof(commit_string_eof) // okay 
#) %from(commit_string) %eof(commit_string_eof) // bad 

); #$debug; 

main := (collector)+; 

답변

1

처음에 a에서 변화가있을 때 나는 연결된 기계 a.b의 최종 상태가 a에 대한 발생 생각 문자는 b입니다. (매뉴얼의 "정규 언어 연산자/연결"참조). 점 출력이 더 최종 상태

점의 출력을 보여줍니다 없다는 사실에도 불구하고

는 최종 상태를 많이 보여줍니다. 7에서 6으로의 전환은 예를 들어 7 개의 최종 결정을 내립니다. 6에서 1로 전환하면 6 개의 최종 결과가됩니다.

+0

일반적으로 Dot 출력은 최종 상태에 대해 두 배의 원을 표시합니다. 나는 그것의 부족이 나를 혼란스럽게 만들었다 고 생각한다. – gibbss

+0

도트 출력에 관해서는 Ragel의 설명서가별로 도움이되지 않습니다. 전에 보았던 모든 그래프는 이중 원으로 최종 상태를 나타냅니다. 위의 사진에서 화살표 끝에있는 작은 원과 점은 정확히 무엇입니까? 내 그래프에서 많은 화살표는 "0/do_date, 69 : 6"처럼 표시됩니다. 0은 전환이 입력 문자를 사용하지 않았 음을 나타내고 do_date는 내가 지정한 동작임을 나타냅니다. 그러나 '69 : 6 '은 무엇을 의미합니까? –

+0

69 : 6은 문자 코드입니다. 대신 캐릭터를보기 위해'-p' 옵션을 ragel에 넘겨 주어야합니다. 작은 원과 점들은 아마도 출구이지만, 나에게 익숙한 예가 없으면 말할 수 없다. – ArtemGr