[Haskell-beginners] University project - weird problem

Daniel Fischer daniel.is.fischer at web.de
Wed Apr 21 19:39:21 EDT 2010


Am Donnerstag 22 April 2010 00:42:51 schrieb Renato dos Santos Leal:
> I've got a university project that demands me to do a program that
> receive a .c file and analyze its syntax using haskell.
> There are just a few things that I have to analyze:
> literal strings, identifiers (in the program: identificadores),
> constants (constantes), operators (operadores) and reserverd
> words(palavras reservadas)
>
> There are two major problems in the program:
>
> (1) I've got this guard in le_bloco: | x `elem` listS = do separador
> (x:xs) but it doesn't seem to work. Every time I enable it I recieve
> this in execution time (after calling verifica)
>
> ERROR - Cannot find "show" function for:
> *** Expression : verifica
> *** Of type    : IO a

I can't reproduce that. It works here (except of the pattern match failure 
at the end because none of your functions handles an empty String).

$ hugs CAnal                                 
__   __ __  __  ____   ___      _________________________________________               
||   || ||  || ||  || ||__      Hugs 98: Based on the Haskell 98 standard               
||___|| ||__|| ||__||  __||     Copyright (c) 1994-2005                                 
||---||         ___||           World Wide Web: http://haskell.org/hugs                 
||   ||                         Bugs: http://hackage.haskell.org/trac/hugs              
||   || Version: September 2006 _________________________________________               

Haskell 98 mode: Restart with command line option -98 to enable extensions

Type :? for help
CAnal> verifica 
Favor visualizar o codigo para ver os bugs e erros do programa
Digite o nome do arquivo de entrada: hello.c                  
#include <identificador>                                      
< <operador>                                                  
stdio <identificador>                                         
. <operador>                                                  
h <identificador>                                             
> <operador>                                                  


int <identificador>
main <identificador>
(){ <separador>     
printf <identificador>
( <separador>         
Hello <identificador> 
World <identificador> 
! <operador>          
\n" <identificador>   
); <separador>        
return <palavra chave>
0 <cte. numerica>     
; <separador>         
} <separador>         

Program error: pattern match failure: le_bloco []

CAnal> :q
[Leaving Hugs]

>
> So I've made one workaround that prints the separator but stops the
> program...I guess the problem is doing the recursivity
>
> (2) My second problem is: when I have one identifier or keyword alone in
> a line or it's the last element of it it just won't print my coment!

That's because you don't look for newlines, so

int
main

is considered to be one token, "int\nmain".

> this is the function:
>
> pPCouI (x:xs) z
>
>     | membroPC z = do{ putStr (z ++ " <palavra chave>\n") ; le_bloco
>     | (x:xs)} otherwise = do{putStr z ; putStr " <identificador>\n" ;
>     | le_bloco
>
> (x:xs)}
>
> *Please help me solving those problems as soon as possible!*
>
> Here is the whole program:
>
> listO = ['+', '-', '*', '/', '%', '^', '=', '>', '<', '.', '|', '&',
> '!', '~']
> listS = [';', '{', '(', ')', '}', '[', ']', ',']
> listC = ['0','1'..'9']
> listCF = listC ++ ['.']
> listA = listO ++ listS ++ [' ']
> listPC =
> ["auto","double","int","struct","break","else","long","switch","case",
>
> "enum","register","typedef","char","extern","return","union","const",
>
> "float","short","unsigned","continue","for","signed","void","default",
>           "goto","sizeof","volatile","do","if","static","while"]
>
> verifica = do
>     putStr ("Favor visualizar o codigo para ver os bugs e erros do
> programa\n")
>     putStr ("Digite o nome do arquivo de entrada: ")
>     arqent <- getLine
>     texto <- readFile arqent
>     le_bloco texto
>
> le_bloco (x:xs)
>
>     | x `elem` listO = do operador (x:xs)
>     | x `elem` listC = do cnum (x:xs)
>
>   --  | x `elem` listS = do separador (x:xs)
>
>     | x `elem` listS = do{ putStr[x] ; putStr " <separador>\n" }
>     | x == '"' = litstr (xs)
>     | x /= ' ' = pchave (x:xs) []
>     | x == ' ' = le_bloco xs
>     | otherwise    = do { putStr "Outro\n" ; le_bloco xs }
>
> separador (x:xs)
>
>     | x `elem` listS = do{ putStr [x] ; separador xs}
>     | otherwise = do{ putStr " <separador>\n" ; le_bloco xs}

That should probably be le_bloco (x:xs) in the otherwise-branch, too. Thus 
it failed to see that "Hello World\n" was a string literal.
And it wouldn't treat

int x=3,y=4;

correctly.

>
> cnum (x:xs)
>
>     | x `elem` listCF = do{ putChar x ; cnum xs}
>     | otherwise = do{ putStr " <cte. numerica>\n" ; le_bloco (x:xs)}
>
> operador (x:xs)
>
>     | x `elem` listO = do{ putChar x ; operador xs}
>     | otherwise = do{ putStr " <operador>\n" ; le_bloco (x:xs)}
>
> litstr (x:xs)
>
>     | x /= '"' = do{ putChar x ; litstr xs}
>     | otherwise = do{ putStr " <literal string>\n" ; le_bloco xs}
>
> pchave (x:xs) ys
>
>     | x `notElem` listA = pchave xs (ys++[x])
>     | otherwise = pPCouI (x:xs) ys
>
> pPCouI (x:xs) z
>
>     | membroPC z = do{ putStr (z ++ " <palavra chave>\n") ; le_bloco
>     | (x:xs)} otherwise = do{putStr z ; putStr " <identificador>\n" ;
>     | le_bloco
>
> (x:xs)}
>
> membroPC x
>
>     | x `elem` listPC = True
>     | otherwise = False
>
> I'm sorry for the bad english, it's been a while since the last time i
> used it =)
> Ah, I'm just starting to learn Haskell, first time i've seen it was like
> a month ago so pretend that I know nothing



More information about the Beginners mailing list