Analyse lexicale sans expressions régulières

9

J'ai regardé quelques lexers dans différentes langues de niveau supérieur ( Python , PHP , Javascript entre autres) et ils semblent tous utiliser des expressions régulières sous une forme ou une autre. Bien que je sois sûr que les regex sont probablement la meilleure façon de le faire, je me demandais s'il y avait un moyen d'obtenir une lexing de base sans expressions régulières, peut-être une sorte d'analyse de chaîne directe ou quelque chose.

Alors oui, est-il possible d'implémenter une sorte de lexing de base dans un langage de niveau supérieur * sans utiliser d'expressions régulières sous aucune forme?

* Les langages de niveau supérieur étant des choses comme Perl / PHP / Python / Javascript, etc. Je suis sûr qu'il existe un moyen de le faire en C

Tache
la source
2
On dirait "y a-t-il un livre sur le calcul qui n'utilise pas toutes ces lettres grecques et ces choses bizarres bizarres?"
kevin cline
@kevincline Pourquoi les gens traversent-ils l'Atlantique alors qu'il y a des avions parfaitement bons dans le ciel?
Smudge
1
l'aviron et l'équitation ont des effets secondaires différents.
kevin cline

Réponses:

3

Tout d'abord, il y avait des bibliothèques d'expressions régulières pour C depuis avant que vos langages de "niveau supérieur" ne soient inventés. Je dis simplement que les programmes C ne sont pas aussi podunk que certaines personnes semblent le penser.

Pour la plupart des grammaires, la lexie consiste à rechercher des espaces et quelques autres caractères comme () [] {}; pour diviser les mots, puis en les comparant à une liste de mots clés pour voir si une correspondance existe.

Karl Bielefeldt
la source
1
Je ne voulais pas dire que C ne pouvait pas faire de regex, je voulais dire qu'il avait des fonctionnalités plus puissantes pour faire ce genre de choses. J'imagine qu'il est plus facile de construire un lexer avancé et performant en C qu'un langage de niveau supérieur.
Smudge
1
@sam la complexité et les performances d'un lexer ou d'un analyseur dépendent davantage de la complexité de la langue analysée que des langages dans lesquels l'analyseur est implémenté, donc non.
jk.
+1. Un lexer est incroyablement simple; vous avez juste besoin d'une chaîne, d'un type de données pour vos jetons et d'un tableau de mots clés prédéfinis. La partie la plus délicate concerne les espaces et les commentaires: P
Mason Wheeler
2

Vous pourriez être intéressé par les "analyseurs sans scanner", qui n'ont pas d'étape de tokenisation distincte. Une explication des avantages des analyseurs sans scanner est donnée au début de cet article: Filtres de désambiguïsation pour les analyseurs LR généralisés sans scanner . (Il y a aussi des inconvénients.)

(Les PEG, qui ont été mentionnés dans d'autres réponses, peuvent également être utilisés pour construire des analyseurs sans scanner.)

Ryan Culpepper
la source
1

Il n'y a rien de spécifique dans les expressions régulières. Ils sont simplement un raccourci qui vous permet de générer le code beaucoup plus facilement, et les implémentations sont généralement livrées. Cependant, fondamentalement, les lexers sont des FSM et les expressions régulières ne sont qu'un moyen d'atteindre cet objectif.

DeadMG
la source
0

Bien sûr, vous pouvez utiliser d'autres analyseurs, car chaque langue régulière est également sans contexte. La question se résume vraiment à pourquoi vous voudriez.

Il n'y a rien de plus simple que les expressions régulières (comment pouvez-vous améliorer O (N)?) Et essayer de simplifier n'aidera pas. Vous pouvez toujours utiliser un retour arrière simple comme l'a souligné Jetti, bien que je recommande de l'éviter si possible.

Si vous allez utiliser un analyseur plus avancé pour lexing, vous n'avez probablement pas du tout besoin d'une phase de lexing. En fait, les raisons pour lesquelles nous avons une phase de lexing est qu'il est plus rapide d'analyser les jetons lexés que d'analyser les caractères, ce qui simplifie considérablement notre étape d'analyse. Ainsi, en utilisant un analyseur plus avancé, vous perdez simplement tout avantage de lexing en premier lieu.

Pubby
la source
Alors, comment regex le fait-il? Ne faudrait-il pas encore que ce soit caractère par caractère (pour la plupart des motifs utilisés en lexing au moins)?
Jetti
@Jetti Oui, bien sûr.
Pubby
Il serait tout aussi facile de lire chaque personnage, puis de revenir en arrière si nécessaire pour retirer un jeton. Ce serait plus de code mais pas plus difficile.
Jetti
@Jetti Je n'arrive pas à voir comment le retour en arrière naïf est meilleur.
Pubby
Je n'ai jamais dit mieux. Mais l'OP a demandé s'il y avait d'autres moyens et c'est un autre moyen qui n'est pas un analyseur avancé.
Jetti
0

Il est judicieux soit de faire une analyse lexicale avec des expressions régulières, soit de sauter cette passe du tout et de faire une analyse lexerless beaucoup plus flexible et puissante avec PEG ou GLR.

SK-logic
la source