2013-01-18 2 views
0

delimeter로 일부 공백을 사용할 수 있습니까? 내 말은 ...구문 분석의 공백 문자와 연산자의 유사 함

주어진 파이썬 연산자 우선 구문 분석기, 자연어와 연산자를 섞어주고 싶다. 즉, 노트 작성을위한 약어로 'caffeine : A1 antagonist -> caffeine : peripheral stimulant'에는 해석 'caffeine is an A1 antagonist implies that it is a peripheral stimulant'이있다.

나는이

operands = delimitedList(Word(alphanums), delim=',') 
# delim=' ' obviously doesn't work 

precedence = [ 
    (":", 2, opAssoc.LEFT), 
    ("->", 2, opAssoc.LEFT), 
    ] 

parser = operatorPrecedence(operands, precedence) 

def parse(s): return parser.parseString(s, parseAll=True) 

print parse('a:b -> c : d e') 

수 같은과 함께이 parse('a:b -> c : d e')

[[['a', ':', 'b'], '->', ['c', ':', ['d', 'e']]]]로 구문 분석 할 수있게하려면?

+0

여기서 첫 번째로 구분 기호를 사용합니까? 어디에도 쉼표가 없으며'parser = operatorPrecedence (Word (alphanums), precedence) '를 사용하는 것과 동일한 효과가 있습니다. – abarnert

+1

또한 공백이 보존 된 구문을 반환하는 대신'b' 및'd' 용어를 공백으로 분리 하시겠습니까? 왜냐하면 후자는 사소한 것 ('Word (alphanums + '')')을 사용하는 것뿐만 아니라 의도 한 유스 케이스에 더 유용하게 보이기 때문입니다.''A1 길항제 '와''주변 자극제''는 주변 표식의 용어이지'''A1'',''길항제''''''말초'',''자극제'''는 아닙니다. – abarnert

+0

오른쪽. '단어 (영숫자 + '))'가 작동합니다. 감사! –

답변

4

생각한 후에는 정의하려는 언어가 모호하다고 생각하지만 여러 가지 방법으로 해결할 수 있습니다.

당신이 원하는 :

parse('a:b -> c : d e') 

당신이를 제공하려면 :

[[['a', ':', 'b'], '->', ['c', ':', ['d', 'e']]]] 

당신은 공백 연산자의 역할을 할 것을 암시했습니다. 그렇다면 'c :'의 컨텍스트에서 왜 연산자가 아닌가? 운영자가 아닌 때와 운영자가 아닌 경우에 대한 규칙은 무엇입니까?

어느 쪽이든, 또는 각 피연산자가 공백으로 구분 된 단어 목록이되도록하려는 경우. 하지만이 경우 ['a'] 대신 'a'이 표시되는 이유는 무엇입니까? 각각의 피연산자가리스트이거나, 그 중 하나도 없다. 분명히 위치에 의존하지 않으며 다른 규칙을 지정하지 않았습니다.

염두에 두어야 할 그럴듯한 규칙이 하나 이상 있습니다. 단일 요소 목록을 그 요소로 축소하는 피연산자를 축소하십시오. 그러나 이것은 이상한 규칙입니다. 나중에이 구문 분석 트리를 사용하는 목적에 상관없이 하나의 단어를 하나의 단어 목록처럼 취급하는 코드를 작성하여 동일한 규칙을 효과적으로 반대로 사용해야합니다 . 그래서 ... 왜 그런 식으로?

나는 세 더 나은 대안을 생각할 수 있습니다 :

  1. 단어의 공백으로 구분 된 목록으로 모든 연산을 필요로한다.
  2. 피연산자의 중간에 공백을 허용하십시오.
  3. 기본 여백 처리를 사용하고 모든 연산자의 양쪽에 여러 용어를 허용하십시오.

이러한 것들은 매우 쉽게 파싱 할 수 있으며 매우 사용하기 쉬운 파스 트리를 제공합니다. # 2로 갈 것입니다. 그러나 위의 설명에서 이미 설명한 방법을 이미 설명 했으므로 여기에서 # 3을 수행하겠습니다.

>>> operands = OneOrMore(Word(alphanums)) 
>>> precedence = [ 
...  (":", 2, opAssoc.LEFT), 
...  ("->", 2, opAssoc.LEFT), 
...  ] 
>>> parser = operatorPrecedence(operands, precedence) 
>>> def parse(s): return parser.parseString(s, parseAll=True) 
>>> print(parse('a:b -> c : d e')) 
[[['a', ':', 'b'], '->', ['c', ':', 'd', 'e']]] 
>>> print(parse('caffeine : A1 antagonist -> caffeine : peripheral stimulant')) 
[[['caffeine', ':', 'A1', 'antagonist'], '->', ['caffeine', ':', 'peripheral', 'stimulant']]] 
관련 문제