2013-03-04 5 views
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) 
+0

왜 질문을 편집하셨습니까? 수정 사항을 적용한 것처럼 보이므로 더 이상 손상되지 않습니다. 누구나 지금이 일을하는 사람은 벽에 머리를 쾅 쾅 대고 부 풀리는 이유를 알아 내려고 노력합니다. – pat

+0

공백은 보통 'lexeme'파서를 사용하여 처리됩니다.이 파서는 관심이있는 토큰 뒤의 공백을 막아줍니다 또한,'else'를 갖기 위해 모든 if를 요구합니까? 자바는 이것을 요구하지 않는다. – pat

+0

@ 답을 읽지 못할 수도 있습니다. 그런 다음 그들은 왜 그것이 부러 졌는지 알게 될 것입니다. 나는 두 개의 구문 분석기를 가지고 있는데, 하나는 If이고 다른 하나는 IfElse이다. 어휘를 살펴 보겠습니다. –

답변

4

당신은 "만약"진술과 "다른"문을 모두 보유하는 변수 stmt을 사용하고 있습니다. 이 수행 할 때 그래서 :

return $ IfElse iff expr stmt el stmt   

을 ... 나는 stmt 만 "다른"부분에서는 가장 최근에 할당 된 값을 포함 추측 것입니다.

+0

그레이트 캐치, 고마워요. –

관련 문제