2012-04-19 2 views
1

저는 대학에서 스칼라 결합자를 사용하여 명제 논리를 파싱하는 과제를 설정했으며이 작업을 진행하면서 머리카락을 찢어 버릴 예정입니다 몇 시간 동안 그리고 첫 번째 단계를 지나칠조차 수 없습니다.스 카이 결합자를 사용하여 명제 로직을 구문 분석합니다.

초기 부분은 제공된 EBNF 양식을 준수하는 인식 유형 (유형은 이미 별도로 제공됨)을 작성하는 인식자를 작성하는 것입니다.

prop ::= equiv 

equiv ::= impl biArrow impl 
            p <=> q becomes Equivalent (P, Q) 
            p <+> q becomes Not (Equivalent (P, Q)) 
impl ::= disj [impls] 
impls ::= (rightArrow disj)+ 
            p => q becomes Implies (P, Q) 
     | (leftArrow disj)+ 
            p => q becomes Implies (Q, P) 
disj ::= conj (disjOp conj)* 
            p | q becomes Or (P, Q) 
conj ::= neg (conjOp neg) 
            p & q becomes And (P, Q) 
neg ::= negs | pos 
negs ::= negOp neg 
            ~ p  becomes Not (P) 
pos ::= ident | "(" prop ")" 
            ident becomes Literal (true, ident) 

우리가 콤비에 나와있는 스칼라 코드는 오류가 소품의 게으른 (고화질)을 제공한다 ([] 0 또는 1을 의미, + 하나 이상을 의미하고 * 0 개 이상을 의미한다). 위의 코드와 일치하도록 클래스를 작성하기 시작했습니다.하지만 구현하더라도 올바른 오류를 catch하지는 않습니다. 실제로 그 값을 catch하는 방법을 이해하지 못한다고 생각합니다. 파서

trait PropRecognizer extends RegexParsers { 

    val ident = """[a-zA-Z]\w*""".r 

    val biArrow = "<=>" | "<+>" 
    val rightArrow = "=>" 
    val leftArrow = "<=" 
    val disjOp = "|" 
    val conjOp = "&" 
    val negOp = "~" 
    lazy val pos = ident | "("~prop~")" 
    lazy val negs: Parser[Any] = negOp~neg 
    lazy val neg = negs | pos 
    lazy val conj = neg~(conjOp~neg).* | neg 
    lazy val disj = conj~(disjOp~conj).* | conj 
    lazy val impls = (rightArrow~disj).+ | (leftArrow~disj).+ | disj 
    lazy val impl = disj~impls.? | impls 
    lazy val equiv = impl~biArrow~impl | impl 
    lazy val prop: Parser[Any] = rep(equiv) 
} 

어떤 도움

, 나는이 문서를 읽어 봤는데 아직도 내 머리에 클릭이 수없는 것, 구문의 더 나은 윤곽에 힌트가 믿을 도움이 될 것 형성한다. 나는 명제 논리와 파서에 익숙한 사람들에게 이것은 매우 쉬운 문제라고 생각하지만 몇 시간 째 머리를 긁적이고 조금씩 해킹에 가까워지고있다.

편집 : UPDATE 주어진 구문은 내가 불통, 그래서 하나 개의 항목으로 잘못 지금은 완벽하게 작동합니다 :

lazy val prop: Parser[Any] = rep(equiv) 
lazy val equiv: Parser[Any] = impl~(biArrow~impl).? 
    lazy val impl = disj~impls.? 
    lazy val impls: Parser[Any] = (rightArrow~disj).+ | (leftArrow~disj).+ 
    lazy val disj = conj~(disjOp~conj).* 
    lazy val conj: Parser[Any] = neg~(conjOp~neg).* 
    lazy val neg: Parser[Any] = negs | pos 
    lazy val negs: Parser[Any] = negOp~neg 
    lazy val pos = ident | "("~prop~")" 

답변

3

당신은 ^^ 운영자/방법을 사용하여 표현 클래스로 구문 분석 된 표현을 변환해야합니다. 예를 들어

lazy val conj: Parser[And] = neg~conjOp~neg ^^ {case p1~_~p2 => And(p1,p2)} 

neg 모든 수식을 표현하기위한 수퍼 클래스이며 And 인자로서 두 명제 소요 형 Parser[Proposition],의 것을 가정한다. Parser[T]은 일부 입력을 구문 분석하고 그 결과로 T 유형의 값을 리턴한다는 것을 알아야합니다.

또한 Parser은 공 변하지 않으므로 어떤 제안을 구문 분석해야 할 곳에 Parser[And]을 사용할 수 있습니다.

명제 논리에 대한 구문 분석기의 예는 this입니다.

+0

제대로 컴파일하는 데 문제가 있습니다. 초기 단계에서 명제로 구문을 분석 한 다음 유형을 지정하고 특정 사례를 지정하려고했지만 그 중 하나는 대부분의 문제는 올바른 암시를했다고 말하면서 검사를하는 것입니다. 왼쪽 암시가 발생하면 자신의 괄호 안에서 발생합니다. 진술이 무효가되는 것들. – Schroedinger

+0

@Schroedinger 그래서 두 개의 경우를 대괄호로 묶지는 않습니까? case p1 ~ "case p1 ~"<" ~ p2 => ...'와 같이 :'~'에 대한 접두사 문법을 사용해야 만하는 경우가 있습니다 : ~ (p1, ~ ("=" > ", p2))'이 문제가 될 수 있습니다. – ziggystar

+0

@Schroedinger 제 편집 내용보기, 링크를 추가했습니다. – ziggystar

관련 문제