Así que estoy tratando de poner en práctica una gramática muy simple para las declaraciones de una sola línea:Ambigüedad gramatical: ¿por qué? (Problema es: "(a)" vs "(az)")
# Grammar
c : Character c [a-z0-9-]
(v) : Vowel (= [a,e,u,i,o])
(c) : Consonant
(?) : Any character (incl. number)
(l) : Any alpha char (= [a-z])
(n) : Any integer (= [0-9])
(c1-c2) : Range from char c1 to char c2
(c1,c2,c3) : List including chars c1, c2 and c3
Examples:
h(v)(c)no(l)(l)jj-k(n)
h(v)(c)no(l)(l)(a)(a)(n)
h(e-g)allo
h(e,f,g)allo
h(x,y,z)uul
h(x,y,z)(x,y,z)(x,y,z)(x,y,z)uul
Estoy utilizando el generador de feliz analizador (http : //www.haskell.org/happy/) pero por alguna razón parece haber algún problema de ambigüedad.
El mensaje de error es: "cambio/reducir los conflictos: 1"
Creo que la ambigüedad es con estas dos líneas:
| lBracket char rBracket { (\c -> case c of
'v' -> TVowel
'c' -> TConsonant
'l' -> TLetter
'n' -> TNumber) $2 }
| lBracket char hyphen char rBracket { TRange $2 $4 }
un caso de ejemplo es: "(a)" Vs "(az)"
el lexer daría la siguiente para los dos casos:
(a) : [CLBracket, CChar 'a', CRBracket]
(a-z) : [CLBracket, CChar 'a', CHyphen, CChar 'z', CRBracket]
Lo que no entiendo es cómo esto puede ser ambiguo con un analizador LL [2].
En caso de que ayuda aquí es la definición completa de la gramática feliz:
{
module XHappyParser where
import Data.Char
import Prelude hiding (lex)
import XLexer
import XString
}
%name parse
%tokentype { Character }
%error { parseError }
%token
lBracket { CLBracket }
rBracket { CRBracket }
hyphen { CHyphen }
question { CQuestion }
comma { CComma }
char { CChar $$ }
%%
xstring : tokens { XString (reverse $1) }
tokens : token { [$1] }
| tokens token { $2 : $1 }
token : char { TLiteral $1 }
| hyphen { TLiteral '-' }
| lBracket char rBracket { (\c -> case c of
'v' -> TVowel
'c' -> TConsonant
'l' -> TLetter
'n' -> TNumber) $2 }
| lBracket question rBracket { TAny }
| lBracket char hyphen char rBracket { TRange $2 $4 }
| lBracket listitems rBracket { TList $2 }
listitems : char { [$1] }
| listitems comma char { $1 ++ [$3] }
{
parseError :: [Character] -> a
parseError _ = error "parse error"
}
Gracias!
Gracias ... eso resolvió el problema (de todos modos, las listas con un elemento son inútiles en este caso, así que las eliminé). Pero, ¿qué quieres decir con la declaración del caso? – o1iver
@ o1iver: solo que probablemente quiera agregarle un caso predeterminado para manejar caracteres individuales que no son uno de 'v, c,?, L, n' para señalar un error más significativo que" Patrones no exhaustivos en el caso expresión". – hammar
sí, ya lo tenía antes, pero no estaba seguro. Creo que lanzaré un error si eso sucede ... Aunque supongo que tendré que echar un vistazo a los documentos de Happy relacionados con el manejo de errores en general. Gracias de nuevo... – o1iver