Vous avez une erreur rule
dans votre cahier des charges.
Un fichier de spécification a la déclaration suivante :
declarations
%%
rules
%%
programs
Où un rule
est définie comme suit :
A : BODY ;
Où A est un symbole non terminal, tandis que CORPS se compose de tokens (symboles terminaux), de non-terminaux et de littéraux. Les :
et ;
sont des éléments obligatoires de la syntaxe de la déclaration de règle.
D'où la règle :
.|\n ECHO;
est syntaxiquement incorrect.
Puisque vous essayez simplement d'afficher l'entrée, une implémentation très simple basée sur la fonction calc.y
serait le suivant (fichier echo.y ) :
règles
%%
in : /* empty */
| in input '\n'
{ fmt.Printf("Read character: %s\n", $2) }
;
input : CHARACTER
| input CHARACTER
{ $$ = $1 + $2 }
;
programme
%%
type InputLex struct {
// contains one complete input string (with the trailing \n)
s string
// used to keep track of parser position along the above imput string
pos int
}
func (l *InputLex) Lex(lval *InputSymType) int {
var c rune = ' '
// skip through all the spaces, both at the ends and in between
for c == ' ' {
if l.pos == len(l.s) {
return 0
}
c = rune(l.s[l.pos])
l.pos += 1
}
// only look for input characters that are either digits or lower case
// to do more specific parsing, you'll define more tokens and have a
// more complex parsing logic here, choosing which token to return
// based on parsed input
if unicode.IsDigit(c) || unicode.IsLower(c) {
lval.val = string(c)
return CHARACTER
}
// do not return any token in case of unrecognized grammer
// this results in syntax error
return int(c)
}
func (l *InputLex) Error(s string) {
fmt.Printf("syntax error: %s\n", s)
}
func main() {
// same as in calc.y
}
func readline(fi *bufio.Reader) (string, bool) {
// same as in calc.y
}
Pour compiler et exécuter ce programme, procédez comme suit à l'invite de commande :
go tool yacc -o echo.go -p Input echo.y
go run echo.go
Comme vous pouvez le constater, vous devrez définir vos propres règles d'analyse dans le fichier Lex
méthode. La structure InputLex
est conçu pour conserver les valeurs pendant que votre entrée est analysée. InputSymType
est généré automatiquement et est défini par le %union
déclarée dans le declaration
partie du cahier des charges.
Pour autant que je sache, il n'y a pas de moyen d'utiliser directement JISON ou une expression rationnelle pour faire la correspondance en utilisant la fonction de go. yacc
outil. Vous devrez peut-être jeter un coup d'œil à d'autres bibliothèques.
Plus de détails sont disponibles ici : http://dinosaur.compilertools.net/yacc/
Code complet ici : https://play.golang.org/p/u1QxwRKLCl