2012-03-02 2 views
1

나는 Haskell Parsec 라이브러리를 사용한 문자열 파싱을 위해이 파서를 가지고있다. 내 언어로Parsec을 사용한 문자열 토큰의 어휘 분석

myStringLiteral = lexeme (
     do str <- between (char '\'') 
        (char '\'' <?> "end of string") 
        (many stringChar) 
        ; return (U.replace "''" "'" (foldr (maybe id (:)) "" str)) 

     <?> "literal string" 
     ) 

문자열이 '' (예 : 'this is my string')의 내부 알파 NUM 문자로 정의하지만, 이러한 문자열은 또한 내부 '를 포함 할 수 있습니다 (이 경우 ' 다른 ', 전로 이스케이프해야합니다 'this is my string with '' inside of it').

문자열의 구문 분석 중에 '이 나타날 때를 기다리며, 다른 문자가있는 경우 ' (없으면 반환하고, 문자열의 끝을 반환)을 결정합니다. 그러나 나는 그것을 어떻게하는지 모른다. 어떤 아이디어? 감사!

답변

5

, 당신은, 이스케이프 된 작은 따옴표를 위해

escapeOrStringChar :: Parser Char 
escapeOrStringChar = try (string "''" >> return '\'') <|> stringChar 

을 특별한 경우를 만들 수 있고 당신은 그것을 위해 stringLiteral을 사용할 수 있습니다

myStringLiteral = lexeme $ do 
    char '\'' 
    str <- many escapeOrStringChar 
    char '\'' <?> "end of string" 
    return str 
+0

우수! 고마워요! –

-1

파섹은 LL (1) 언어 (details) 만 취급합니다. 파서가 한 번에 하나의 심볼 만 볼 수 있음을 의미합니다. 귀하의 언어는 LL (2)입니다. 자신의 언어를 파싱하기 위해 자신의 FSM을 작성할 수 있습니다. 또는 파싱하기 전에 텍스트를 변형하여 LL (1)로 만들 수 있습니다.

실제로 Parsec은 어휘가 아닌 구문 분석을 위해 설계되었습니다. 좋은 아이디어는 다른 도구로 어휘 분석을하고 Parsec을 사용하여 문자 시퀀스가 ​​아닌 어휘 시퀀스를 파싱하는 것입니다.

구문이 보인다처럼 간단 경우
+2

파섹은 'try'결합자를 사용하여 비 LL (1) 문법을 처리 할 수 ​​있습니다. – bzn

+0

Parsec에서는 문자 레벨 파서가 쉽기 때문에 _ 스캐너가없는 파서로 간주 될 수 있습니다. 별도의 렉서를 사용할 수는 있지만 (Daan Leijen의 원래 매뉴얼에서 다루었습니다.) 상당한 볼 리어 플레이트가 필요합니다. –

+1

또한 Parsec은 상황에 맞는 구문 분석 (응용 프로그램뿐만 아니라 모나드이기도 함)을 처리 할 수 ​​있으므로 다시 LL (1)보다 큰 문법 클래스를 처리 할 수 ​​있습니다. –