0

我有一个 ifelse 解析器,它应该能够用
类 java 语言解析嵌入的 ifelse 语句,但它无法识别内部 ifelse。另外,如果有人可以向我展示一种更好的方法来处理 ifelseParser 中的空格,我将不胜感激。

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 没有拾取整个表达式,缺少内部 if-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)
4

1 回答 1

4

您正在使用该变量stmt来保存“if”语句和“else”语句。所以当你这样做时:

 return $ IfElse iff expr stmt el stmt           

...我猜stmt它只包含最近分配的值,它来自“else”部分。

于 2013-03-04T20:36:08.453 回答