2010-11-12 21 views
2

J'essaye d'écrire un analyseur pour un langage de type Lua, en utilisant lex et yacc. C'est un langage sans terminateur de requête forcé (un point-virgule), et cette fonctionnalité ne m'a pas permis de dire si un appel de fonction est une instruction ou une expression.
Par exemple, la fonction suivante:Comment puis-je savoir si un appel de fonction est une expression ou une instruction lors de l'écriture d'un analyseur pour un langage Lua?

function foo() 
    return { x = 5 } 
end 

renverra une table. Voici quelques usages:

foo() -- this is a statement 
t = foo() -- foo is an expression 
a = foo().x -- foo() is a prefix-expression 
print(foo()) -- foo() is an expression 

Je ne peux pas écrire un non-conflit code yacc, parce qu'un simple appel de fonction pourrait être une expression, un préfixe d'expression, ou une déclaration.
Comment puis-je implémenter cette fonctionnalité? L'introduction de terminaisons d'instructions forcées est-elle le seul moyen?

Merci beaucoup.

+1

Vous pouvez jeter un oeil à la grammaire Lua de l'EBNF: http://www.lua.org/manual/5.1/manual.html#8 pour voir comment ils ont implémenté les choses. –

+1

de ce que je vois l'appel de fonction simple ferait partie des expressions/déclarations. Vous avez juste à réorganiser votre grammaire (ce qui rend laid à regarder mais parseable avec yacc) – josefx

Répondre

1

J'avais une tâche similaire à résoudre lors de la mise en œuvre d'un analyseur T-SQL. J'ai fini par inclure le ; comme s'il était obligatoire dans la grammaire, et sur les erreurs de syntaxe j'insérerais un jeton virtuel ; pour terminer l'instruction en cours et ensuite l'analyseur réessayerait la réduction.

Pour mon cas d'utilisation, cela fonctionne très bien, peut-être que cela pourrait aussi fonctionner pour le vôtre.