2014-07-15 4 views
1

축소 된 구문 구문에 대한 문법을 ​​연구하고 중첩 된 확장이있는 걸림돌을 만났습니다.구문 분석을 사용하여 구문 분석 확장 구문

$(error Not implemented for this OS: $(filter XYZ_OS_%, $(.VARIABLES))) 

이 많은 사람들이 함께 투쟁하는 것 중첩 된 표현의 문제에 대한 변형은 다음과 같습니다

는 여기에 우리가 구문 분석 할 작업의 예입니다. 중첩 된 표현 괄호 달러를 포함한 자유 형식 문자열을 포함 할 수 있기 때문에 약간 더 어려운 : (. $ 문자가 여기에 반복하여 이스케이프)

$(error Something went wrong (you owe me $$$$$$.)) 

내가 이것에 대한 예비 문법을 가지고 있지만, text 규칙을 정의하는 방법을 생각할 수 없습니다.

name = Word(alphanums + '_') 
text = CharsNotIn('$)') # This does not work generally. 

expansion = Suppress('$(') + name + Suppress(')') 

sub_expression = Forward() 
expression = ZeroOrMore(sub_expression) 

error = Suppress('$(error ') + expression + Suppress(')') 
info = Suppress('$(info ') + expression + Suppress(')') 
pattern = Word(alphanums + '._%') 
filter = Suppress('$(filter ') + pattern + Suppress(',') + expression + Suppress(')') 

sub_expression << (text | error | filter | info | expansion) 

# This accepts all kinds of invalid Make syntax, 
# but is useful for testing line-by-line. 
test_grammar = OneOrMore(text | expansion | error | filter | info) 

이것은 단순한 사례를 포착했지만 확장에 속하지 않은 괄호와 달러는 실패합니다.

아이디어가 있으십니까? 감사!

+0

일반 변수 확장과 마찬가지로'error','filter' 등을 처리해야한다고 생각합니다. –

+0

@Antti, 고마워. 나는 우리가 같은 결론에 도달했다고 생각한다. 불행히도 텍스트 내용을 확장에서 분리하는 데 도움이되지 않는 것 같습니다. –

+0

그게 바로 주석입니다 ... 당신은 어떻게 확장을 먼저 구문 분석하고, 그런 식으로 쉽게 복제하는지 알아 내야합니다. –

답변

0

우리는 그것을 알아 낸 것입니다!

우리는 Make가 $(error)과 친구 사이에 괄호를 허용한다는 것을 알았지 만, 균형이 맞았을 때만 가능합니다. 그렇지 않으면 불투명 텍스트 내부 괄호 텍스트와 일치하는 규칙 :

$(error This(thing(is)crazy) 

그래서 우리는 문법의 중요한 부분 누락되었습니다 : 그렇지 않으면이 같은 매다는 식으로 어떻게 해야할지 것,이 방법이 있습니다.

그런 다음 우리는 원래 SkipTo을 찾았습니다. 원래 우리가 찾고 있던 종류였습니다. 그것은 우리가 할 수가 일치에 전달 된 규칙까지 모든 텍스트를 소비 (감소) :

name = Word(alphanums + '_') 
expansion = Suppress('$(') + name + Suppress(')') 

end_of_text = Literal('$(') | Literal('(') | Literal(')') 
text = NotAny(end_of_text) + SkipTo(end_of_text).leaveWhitespace() 
parenthesized_text = Combine(Literal('(') + SkipTo(')').leaveWhitespace() + Literal(')')) 

sub_expression = Forward() 
expression = ZeroOrMore(sub_expression | parenthesized_text | text) 

error = Suppress('$(error ') + expression + Suppress(')') 

sub_expression << (error | expansion) 

grammar = OneOrMore(error) 

우리는 우리가하는 식의 내부에있을 때, 텍스트가 괄호 문자 및 확장 인터리브 덩어리에 오는 것을 보았다. 텍스트를 인식하려면 확장을 시작하는 $(을 찾으십시오. 괄호 안의 텍스트를 시작하는 (과 전체를 끝내는 )이 있습니다.

기본적으로 error$(error과 일치하고 표현식 시퀀스가 ​​뒤따 랐으며이를 트리로 깔끔하게 반환합니다. 예 : 지금 볼

error: $(error 
    text: Something went wrong 
    parenthesized_text: (you owe me.) 
    text: Status: 
    expansion: $(status) 

이 아마, 올바른 예를 들면 아니라고 :로

$(error Something went wrong (you owe me.) Status: $(status)) 

는 구문 분석 우리는 괄호 안의 텍스트 안에 확장을 인식하지 못합니다. 우리가 알아낼 수 있는지 알게 될 것입니다.

내가 실제로 설명 할 수없는 유일한 이유는 NotAnytext에 필요하며, 파서가 없으면 중단되므로 규칙을 시작하는 데 필요한 것이 있다고 생각됩니다.

희망이 있으면 다른 사람에게 도움이됩니다.

관련 문제