0
java와 유사한 언어로 내장 된 ifelse 문을 구문 분석 할 수 있어야하는 것보다 ifelse 파서가 있지만 내부 ifelse를 인식하지 못합니다. 또한 ifelseParser에서 공백을 처리하는 더 나은 방법을 누군가가 보여줄 수 있다면 감사히 여길 것입니다. 구문 분석기를 Parsec에서 반복적으로 사용하기
if (~(position > 16)) {
if (~((value & mask) = 0)) {
do Memory.poke(8000 + position, 1);
} else {
do Memory.poke(8000 + position, 0);
}
} else { let loop = false; }
ifelseParser
은 내부 경우-else 문 누락, 전체 표현식을 따기되지 않습니다.Right (IfElse "if" (ExprOpTerm (Unary "~" (ExprOpTerm (SimpleExpr (ExprOpTerm
(VarTerm "position") [(">",IntConst 16)])) [])) []) [Let "let" "loop"
(ExprOpTerm (KeywordTerm "false") [])] "else" [Let "let" "loop"
(ExprOpTerm (KeywordTerm "false") [])])
data Statement = Let Keyword VarName Expr
| SubLet Keyword VarName Expr Expr
| If Keyword Expr [Statement]
| IfElse Keyword Expr [Statement] Keyword [Statement]
| While Keyword Expr [Statement]
| Do Keyword SubCall
| ReturnExp Keyword Expr
| NoReturn
| Return Keyword deriving (Show)
ifelseParser :: Parser Statement
ifelseParser = do
whiteSpace
iff <- reserved' "if"
whiteSpace
char '('
whiteSpace
expr <- getExprParser
whiteSpace
char ')'
whiteSpace
char '{'
whiteSpace
stmt <- many1 statementsParser
whiteSpace
char '}'
whiteSpace
el <- reserved' "else"
whiteSpace
char '{'
whiteSpace
stmts <- many1 statementsParser
whiteSpace
char '}'
whiteSpace
return $ IfElse iff expr stmt el stmts
statementsParser :: Parser Statement
statementsParser = do
try subLetParser <|> try letParser <|> try whileParser <|>
try ifelseParser <|> try ifParser <|>
try doParser <|> (try returnExpParser <|> try returnParser)
subRoutineParser :: Parser Term
subRoutineParser = do
whiteSpace
sub <- subCallParser
return $ Subroutine sub
getExprParser :: Parser Expr
getExprParser = do
whiteSpace
term <- (try subRoutineParser <|>
try intVal <|>
try stringVal <|>
try keyWordVal <|>
try varExpParser <|>
try varVal <|>
try simpleExpr <|>
try unaryOpExpr)
op <- many getExpP
return $ ExprOpTerm term op
getExpP :: Parser (String,Term)
getExpP = do
whiteSpace
op <- choice $ map string ops
term <- (try subRoutineParser <|>
try intVal <|>
try stringVal <|>
try keyWordVal <|>
try varExpParser <|>
try varVal <|>
try simpleExpr <|>
try unaryOpExpr)
return $ (op,term)
왜 질문을 편집하셨습니까? 수정 사항을 적용한 것처럼 보이므로 더 이상 손상되지 않습니다. 누구나 지금이 일을하는 사람은 벽에 머리를 쾅 쾅 대고 부 풀리는 이유를 알아 내려고 노력합니다. – pat
공백은 보통 'lexeme'파서를 사용하여 처리됩니다.이 파서는 관심이있는 토큰 뒤의 공백을 막아줍니다 또한,'else'를 갖기 위해 모든 if를 요구합니까? 자바는 이것을 요구하지 않는다. – pat
@ 답을 읽지 못할 수도 있습니다. 그런 다음 그들은 왜 그것이 부러 졌는지 알게 될 것입니다. 나는 두 개의 구문 분석기를 가지고 있는데, 하나는 If이고 다른 하나는 IfElse이다. 어휘를 살펴 보겠습니다. –