2017-11-16 11 views
2

기본 컴퓨터 지침을 파싱하는 코드를 작성하고 있습니다. 내 입력 문자열이예상되는 것보다 더 많은 일치 항목을 찾을 수 없습니다.

같은과 같은 나는 결과를 기대 해요 :

<line> 
    <instruction> 
    <type>ADD</type> 
    <args> 
     <ITEM>input1</ITEM> 
     <ITEM>input2</ITEM> 
    </args> 
    </instruction> 
    <instruction> 
    <type>DEL</type> 
    <args> 
     <ITEM>input3</ITEM> 
    </args> 
    </instruction> 
</line> 
<line> 
    <instruction> 
    <type>SUB</type> 
    <args> 
     <ITEM>input1</ITEM> 
     <ITEM>input2</ITEM> 
    </args> 
    </instruction> 
    <instruction> 
    <type>INS</type> 
    <args> 
     <ITEM>input3</ITEM> 
    </args> 
    </instruction> 
</line> 

내 실제 결과는 그러나 라인과 명령 파서는 것, 내가 무엇을 찾고의 일반적인 구조를 가지고 잘못된 위치에서 일치하거나 라벨이 잘못된 위치에 나타납니다.

실제 결과 : 결과

어떤 이유
[[['OTE', ['output1']]], [['XIO', ['input2']], ['OTE', ['output2']]]] 
- branch: [[['OTE', ['output1']]], [['XIO', ['input2']], ['OTE', ['output2']]]] 
    [0]: 
    [['OTE', ['output1']]] 
    - instruction: ['OTE', ['output1']] 
     - args: ['output1'] 
     - type: 'OTE' 
    [1]: 
    [['XIO', ['input2']], ['OTE', ['output2']]] 
    - instruction: ['OTE', ['output2']] 
     - args: ['output2'] 
     - type: 'OTE' 

<line> 
    <line> 
    <instruction> 
     <type>ADD</type> 
     <args> 
     <ITEM>input1</ITEM> 
     <ITEM>input2</ITEM> 
     </args> 
    </instruction> 
    <instruction> 
     <type>DEL</type> 
     <args> 
     <ITEM>input3</ITEM> 
     </args> 
    </instruction> 
    </line> 
    <instruction> 
    <instruction> 
     <type>SUB</type> 
     <args> 
     <ITEM>input1</ITEM> 
     <ITEM>input2</ITEM> 
     </args> 
    </instruction> 
    <instruction> 
     <type>INS</type> 
     <args> 
     <ITEM>input3</ITEM> 
     </args> 
    </instruction> 
    </instruction> 
</line> 

덤프 라인 전체 구조 위에 일치하고, 명령의 두 번째 줄은 단일 명령으로 일치한다 그룹. 나는 instruction 행에 .setDebug() 함수를 사용하려고 시도했지만 결과를 해석하는 방법을 모르겠습니다. 마지막으로 라인이 Word (Word) 패턴을 따르지 않기 때문에 명령어와 일치해야하는 이유가 표시되지 않습니다.

내 코드 :

#!python3 
from pyparsing import nestedExpr,alphas,Word,Literal,OneOrMore,alphanums,delimitedList,Group,Forward 

theInput = r"ADD(input1,input2) DEL(input3), SUB(input1,input2) INS(input3)" 

instructionType = Word(alphanums+"_")("type") 
argument = Word(alphanums+"_[].") 
arguments = Group(delimitedList(argument))("args") 
instruction = Group(instructionType + Literal("(").suppress() + arguments + Literal(")").suppress())("instruction") 

line = (delimitedList(Group(OneOrMore(instruction))))("line") 

parsedInput = line.parseString(theInput).asXML() 
print(parsedInput) 

디버그 출력 : 내가 잘못 뭐하는 거지

Match Group:({W:(ABCD...) Suppress:("(") Group:(W:(ABCD...) [, W:(ABCD...)]...) Suppress:(")")}) at loc 0(1,1) 
Matched Group:({W:(ABCD...) Suppress:("(") Group:(W:(ABCD...) [, W:(ABCD...)]...) Suppress:(")")}) -> [['ADD', ['input1', 'input2']]] 
Match Group:({W:(ABCD...) Suppress:("(") Group:(W:(ABCD...) [, W:(ABCD...)]...) Suppress:(")")}) at loc 18(1,19) 
Matched Group:({W:(ABCD...) Suppress:("(") Group:(W:(ABCD...) [, W:(ABCD...)]...) Suppress:(")")}) -> [['DEL', ['input3']]] 
Match Group:({W:(ABCD...) Suppress:("(") Group:(W:(ABCD...) [, W:(ABCD...)]...) Suppress:(")")}) at loc 30(1,31) 
Exception raised:Expected W:(ABCD...) (at char 30), (line:1, col:31) 
Match Group:({W:(ABCD...) Suppress:("(") Group:(W:(ABCD...) [, W:(ABCD...)]...) Suppress:(")")}) at loc 32(1,33) 
Matched Group:({W:(ABCD...) Suppress:("(") Group:(W:(ABCD...) [, W:(ABCD...)]...) Suppress:(")")}) -> [['SUB', ['input1', 'input2']]] 
Match Group:({W:(ABCD...) Suppress:("(") Group:(W:(ABCD...) [, W:(ABCD...)]...) Suppress:(")")}) at loc 50(1,51) 
Matched Group:({W:(ABCD...) Suppress:("(") Group:(W:(ABCD...) [, W:(ABCD...)]...) Suppress:(")")}) -> [['INS', ['input3']]] 
Match Group:({W:(ABCD...) Suppress:("(") Group:(W:(ABCD...) [, W:(ABCD...)]...) Suppress:(")")}) at loc 62(1,63) 
Exception raised:Expected W:(ABCD...) (at char 62), (line:1, col:63) 

?

+0

'asXML'을 사용하여 결과를 인쇄하는 대신'dump'를 사용하십시오. – PaulMcG

+0

@PaulMcG 도움에 감사드립니다! 원래 질문에 덤프를 추가했습니다. – Seth

+0

:) 당신은'print (line.parseString (theInput))를했습니다.덤프)', 당신은'print (line.parseString (theInput) .dump())'를해야합니다. – PaulMcG

답변

0

코드에 대한 귀하의 덤프 출력은이 같은 외모를 게시 :

ADD(input1,input2) DEL(input3), SUB(input1,input2) INS(input3) 

[[['ADD', ['input1', 'input2']], ['DEL', ['input3']]], [['SUB', ['input1', 'input2']], ['INS', ['input3']]]] 
- line: [[['ADD', ['input1', 'input2']], ['DEL', ['input3']]], [['SUB', ['input1', 'input2']], ['INS', ['input3']]]] 
    [0]: 
    [['ADD', ['input1', 'input2']], ['DEL', ['input3']]] 
    - instruction: ['DEL', ['input3']] 
     - args: ['input3'] 
     - type: 'DEL' 
    [1]: 
    [['SUB', ['input1', 'input2']], ['INS', ['input3']]] 
    - instruction: ['INS', ['input3']] 
     - args: ['input3'] 
     - type: 'INS' 

우리는 모든 지침을 구문 분석하는 덤프() 출력에서 ​​볼 수 있지만, 각 그룹의 마지막 명령은 아래에 표시됩니다 "명령"이름. 이는 Python dict처럼 여러 값 (ZeroOrMore 또는 OneOrMore에서 가져올 수 있음)이 동일한 키로 지정 될 때 마지막 값만 유지되기 때문에 발생합니다.

두 가지 해결책이 있습니다. 여러 값이 주어진 이름을 저장해야하는 경우 대한 파싱의 시간도 있습니다

[[['ADD', ['input1', 'input2']], ['DEL', ['input3']]], [['SUB', ['input1', 'input2']], ['INS', ['input3']]]] 
- line: [[['ADD', ['input1', 'input2']], ['DEL', ['input3']]], [['SUB', ['input1', 'input2']], ['INS', ['input3']]]] 
    [0]: 
    [['ADD', ['input1', 'input2']], ['DEL', ['input3']]] 
    [0]: 
     ['ADD', ['input1', 'input2']] 
     - args: ['input1', 'input2'] 
     - type: 'ADD' 
    [1]: 
     ['DEL', ['input3']] 
     - args: ['input3'] 
     - type: 'DEL' 
    [1]: 
    [['SUB', ['input1', 'input2']], ['INS', ['input3']]] 
    [0]: 
     ['SUB', ['input1', 'input2']] 
     - args: ['input1', 'input2'] 
     - type: 'SUB' 
    [1]: 
     ['INS', ['input3']] 
     - args: ['input3'] 
     - type: 'INS' 

: 당신은 그냥 각 하위 목록에 구문 분석 지침을 얻을 수 있도록 하나는 ("명령") 결과의 이름을 제거하는 것입니다. setResultsName() 메서드에는이 동작을 가능하게하는 선택적 인수 listAllMatches이 있습니다. setResultsName에 대한 호출 바로 가기를 사용하는 경우, 당신은 listAllMatches=True를 전달할 수 없습니다 - 대신 '*'로 결과 이름을 종료 :이 출력 제공

instruction = Group(instructionType 
           + Literal("(").suppress() 
           + arguments 
           + Literal(")").suppress())("instruction*") 

:

[[['ADD', ['input1', 'input2']], ['DEL', ['input3']]], [['SUB', ['input1', 'input2']], ['INS', ['input3']]]] 
- line: [[['ADD', ['input1', 'input2']], ['DEL', ['input3']]], [['SUB', ['input1', 'input2']], ['INS', ['input3']]]] 
    [0]: 
    [['ADD', ['input1', 'input2']], ['DEL', ['input3']]] 
    - instruction: [['ADD', ['input1', 'input2']], ['DEL', ['input3']]] 
     [0]: 
     ['ADD', ['input1', 'input2']] 
     - args: ['input1', 'input2'] 
     - type: 'ADD' 
     [1]: 
     ['DEL', ['input3']] 
     - args: ['input3'] 
     - type: 'DEL' 
    [1]: 
    [['SUB', ['input1', 'input2']], ['INS', ['input3']]] 
    - instruction: [['SUB', ['input1', 'input2']], ['INS', ['input3']]] 
     [0]: 
     ['SUB', ['input1', 'input2']] 
     - args: ['input1', 'input2'] 
     - type: 'SUB' 
     [1]: 
     ['INS', ['input3']] 
     - args: ['input3'] 
     - type: 'INS' 

당신이 선택할 수있는 방법 당신은 더 편안합니다.