2016-10-03 9 views
1

Grako와 Python을 사용하여 Cisco IOS 및 ASA 구성을위한 파서를 작성하려고합니다. 예를 들어, 'description'키워드는 interface 범위 안에 있어야하지만 interface에 대한 옵션은 여러 개이며 모두 선택 사항이며 순서가 바뀔 수 있습니다. 예를 들어 EBNF에서 '범위가 지정된'키워드를 나타내는 방법을 찾으려고합니다. 장치간에, 나는) 생각 :EBNF에서 범위를 설명하는 방법은 무엇입니까?

interface Vlan1435 
nameif untrust 
description the outside interface for customer X 
bridge-group 1 
security-level 0 

펄 Grako 유사하게 나타납니다 구문 분석 :: Recdescent 모듈을 사용 Farly라는 펄 응용 프로그램에 내가 예에 발견 한 가장 가까운. 거기에서

나는 재귀 정의의이 유형이 있습니다

@@eol_comments :: /!([^\n]*?)\n/ 
@@whitespace :: /[\t ]+/ 

start 
    = 
    file_input $ 
    ; 


file_input 
    = 
    {NEWLINE | asa_line} 
    ; 


asa_line 
    = 
     'names' NEWLINE 
    | interface NEWLINE 
    ; 

interface 
    = 
    'interface' string NEWLINE interface_options 
    ; 


interface_options 
    = 
    if_name | sec_level | if_addr | if_bridgegroup | NEWLINE 
    ; 


if_bridgegroup 
    = 
    'bridge-group' digit NEWLINE interface_options 
    ; 


if_name 
    = 
    'nameif' string NEWLINE interface_options 
    ; 


sec_level 
    = 
    'security-level' digit NEWLINE interface_options 
    ; 

을하지만 이상한 중첩 된 AST를 만들어 내고는 "다시"하지 않습니다 다음 구성에서 두 번째 인터페이스 또는 다른 것을 감지 .

이러한 종류의 범위는 일반적으로 EBNF에서 어떻게 정의됩니까? (이 유형에 대한 유용한 자습서가 있습니까? 내 Google -fu는 Grako 또는 파서에 대해 일반적으로 아무 것도 표시하지 않았습니다)

답변

1

내가 사용하는 트릭은 옵션을 사용할 수있는 경우에도 반복을 사용하는 것입니다.

interface_options 
    = 
    { @+:(if_name | sec_level | if_addr | if_bridgegroup) NEWLINE}* 
    ; 

필요한 경우 의미 작업을 사용하여 옵션이 반복되지 않는지 확인할 수 있습니다.

+0

감사합니다. 나는 이것을 대체하는 grako Buffer 클래스와 결합하여 (파이썬과 같은) 들여 쓰기를 수행하는 것이 트릭을 할 것이라고 생각한다. 단지 문서의 한 줄 언급에서 기능적으로 확장해야한다 :-) – AnotherHowie

+0

나는 ' 들여 쓰기를 위해'Buffer'가 필요하다고 생각하지 않습니다. 들여 쓰기를 문법의 토큰으로 정의하고 의미 규칙을 사용하여 깊이/레벨을 추적 할 수 있습니다. 시맨틱 액션을 활성화하기 위해서만 "빈"규칙을 가질 수 있다는 것을 기억하십시오 ('unindent =();'). – Apalala

+0

좋아요, 시도해 볼게요! – AnotherHowie