2012-02-22 2 views
0

연구의 일부로 특정 언어에 대한 파서를 작성하려고합니다. 현재 나는 다음과 같은 코드를 얻는 문제는 내가 원하는 방식으로 일해야 : 위의 코드는 언어의 한 부분을 포함정규식과 스칼라 파서 연결자로 복잡한 언어를 구문 분석 할 수 없습니다.

private def _uw: Parser[UW] = _headword ~ _modifiers ~ _attributes ^^ { 
    case hw ~ mods ~ attrs => new UW(hw, mods, attrs) 
} 

private def _headword[String] = "\".*\"".r | "[^(),]*".r 

private def _modifiers: Parser[List[UWModifier]] = opt("(" ~> repsep(_modifier, ",") <~ ")") ^^ { 
    case Some(mods) => mods 
    case None  => List[UWModifier]() 
} 

private def _modifier: Parser[UWModifier] = ("[^><]*".r ^^ (RelTypes.toRelType(_))) ~ "[><]".r ~ _uw ^^ { 
    case (rel: RelType) ~ x ~ (uw: UW) => new UWModifier(rel, uw) 
} 

private def _attributes: Parser[List[UWAttribute]] = rep(_attribute) ^^ { 
    case Nil => List[UWAttribute]() 
    case attrs => attrs 
} 

private def _attribute: Parser[UWAttribute] = "[email protected]" ~> "[^>.]*".r ^^ (new UWAttribute(_)) 

, 시간과 공간을 절약하기 위해, 나는에 대한 세부 사항에 많이 가지 않을 것이다 전체 언어. _uw 메서드는 첫 번째 부분 만 문자열에 있어야하지만 세 부분으로 구성된 문자열을 구문 분석해야합니다.

_uw 올바르게 이러한 테스트 문자열을 구문 분석 할 수 있어야한다 : 표제어 시작하고 "로 끝나는 경우

test0 
[email protected] 
"test2" 
"test3"[email protected] 
test4.. 
[email protected] 
"test6.."[email protected] 
"[email protected]"[email protected] 
test8(urel>uw) 
test9(urel>uw)[email protected] 
"test10..()[email protected]"(urel>uw)[email protected] 
test11(urel1>uw1(urel2>uw2,urel3>uw3),urel4>uw4)[email protected]@attr2 

그래서, 고려 따옴표 안에 모든 표제어의 일부가 될 수 있습니다. [email protected]으로 시작하는 모든 단어가 큰 따옴표 안에 들어 있지 않으면 표제어의 속성입니다.

예. test5에서 구문 분석기는 표제어로 test5.을 구문 분석하고 특성으로 attr을 구문 분석해야합니다. 그냥. @를 생략하고 앞의 모든 점을 표제어에 넣어야합니다.

그래서 표제어 뒤에 속성 및/또는 수정자가있을 수 있습니다. 순서는 엄격하므로 속성은 항상 수정 자 다음에옵니다. 속성이 있지만 한정자가없는 경우 [email protected]까지의 모든 것을 표제어의 일부로 간주합니다.

주요 문제는 "[^@(]*".r입니다. "(^[\\w\\.]*)((\\.\\@)|$)".r과 같은 모든 종류의 창의적인 대안을 시도했지만 아무 것도 작동하지 않는 것 같습니다. Lookahead 또는 Lookbehind는 파서 결합 자에게 어떤 영향을 미칩니 까? 나는 파싱이나 정규 표현식에 대한 전문가가 아니므로 모든 도움을 환영합니다!

답변

1

나는 "[^@(]*".r이 문제와 관련이 없다고 생각합니다. 나는 이것이 참조 :

(사용하지 않는 것이 좋습니다 스칼라의 이름에 밑줄을 사용하는 방식에 의해,,)는 제 _uw의 일이
private def _headword[String] = "\".*\"".r | "[^(),]*".r 

, 그래서 [email protected]을 구문 분석 할 때, 두 번째 정규 표현식은 모두 일치합니다 그것의!

scala> "[^(),]*".r findFirstIn "[email protected]" 
res0: Option[String] = Some([email protected]) 

나머지 파서에는 남은 것이 없습니다.

"test6 with a " inside of it.."[email protected] 

보기 미리 봐 숨김에 관해서는, 파서 콤비에 영향을주지 않습니다 .* 따옴표를 받아 들일 것입니다 있기 때문에, _headword의 첫 번째 정규 표현식은 다음과 같이이 유효하게 즉,도 문제가 조금도. 정규식이 일치하거나 그렇지 않으면 파서 결합 자 모두가 신경 써야합니다.