2

ある言語のパーセクルールを書くのに問題があります次の言語の定義があります(問題のある部分)

COMMAND ::= ':' WS LITERAL WS {LITERAL WS}* ';'
LITERAL ::= "[CHAR]*" | [^"\ ][^\ ]*

ここで、WSは空白を表し、LITERALは空白または空白を含むことができる引用符で囲まれた文字を除くすべての文字なので、次の関数を記述します。

literal = quotedLiteral <|> many1 (noneOf " ") 
command = do { char ':'
             ; separator
             ; name <- literal
             ; separator
             ; cmds <- endBy literal separator            -- (1)
             ; char ';'                                   -- (2)
             ; return (name, Command cmds)
             }

問題はその記号';'です は有効なリテラルであるため、(1)関数はそれを解析します。したがって、(2)は';'を見つけられないため、解析エラーが発生します。キャラクター。

この問題を克服する方法はありますか:リテラル関数を作成して';'を受け入れないようにする 文字通りまたはどういうわけか修正(2)?


sclvのコメントの後、私は解決策を見つけました:

  literal :: Parser Literal
  literal = -- as desired in sclv (changing parserZero to pzero


  command :: Parser TCommand
  command = do { char ':'
            ; separator
            ; name <- literal <?> "no name"
            ; separator
            ; cmds <- sepEndBy (do { try( literal) }) separator
            ; char ';'
            ; return (name, Command cmds)
            }
4

1 に答える 1

1

1つの(テストされていない)ソリューション1を引き受けます。

literal = quotedLiteral <|> someChars
   where someChars = do 
            res <- many1 (noneOf " \n")
            if (res == ';')
               then parserZero
               else return res
于 2011-06-07T23:26:59.820 に答える