J'essaye de faire un compilateur pour un langage personnalisé pascal en utilisant bison et flex et je finis par obtenir des erreurs de syntaxe pour les programmes qui devraient être corrects selon ma grammaire personnalisée.règles de grammaire bison pour un langage pascal personnalisé
Ma grammaire personnalisée:
<program> ::= program id
<block>
<block> ::= {
<sequence>
}
<sequence> ::= <statement> (; <statement>)*
<brackets-seq> ::= { <sequence> }
<brack-or-stat> ::= <brackets-seq> |
<statement>
<statement> ::= ε |
<assignment-stat> |
<if-stat> |
<while-stat>
<assignment-stat> ::= id := <expression>
<if-stat> ::= if (<condition>)
<brack-or-stat>
<elsepart>
<elsepart> ::= ε |
else <brack-or-stat>
<while-stat> ::= while (<condition>)
<brack-or-stat>
<expression> ::= <optional-sign> <term> (<add-oper> <term>)*
<term> ::= <factor> (<mul-oper> <factor>)*
<factor> ::= constant |
(<expression>) |
id
<condition> ::= <boolterm> (and <boolterm>)*
<boolterm> ::= <boolfactor> (or <boolfactor>)*
<boolfactor> ::= not [<condition>] |
[<condition>] |
<expression> <relational-oper> <expression>
<relational-oper> ::= == | < | > | <> | <= | >=
<add-oper> ::= + | -
<mul-oper> ::= * |/
<optional-sign> ::= ε | <add-oper>
Ma mise en œuvre de la grammaire sur le bison:
%{
#include <stdio.h>
#include <string.h>
int yylex(void);
void yyerror(char *s);
%}
%union {
int i;
char *s;
};
%token <i> INTEGERNUM
%token PROGRAM;
%token OR;
%token AND;
%token NOT;
%token IF;
%token ELSE;
%token WHILE;
%token PLUS;
%token MINUS;
%token MUL;
%token DIV;
%token LSB;
%token RSB;
%token LCB;
%token RCB;
%token LEFTPAR;
%token RIGHTPAR;
%token ID;
%token INT;
%token ASSIGN;
%token ISEQUAL;
%token LTHAN;
%token GTHAN;
%token NOTEQUAL;
%token LESSEQUAL;
%token GREATEREQUAL;
%left '+' '-'
%left '*' '/'
%%
program:
PROGRAM ID block
;
block:
LCB RCB
|LCB sequence RCB
;
sequence:
statement ';'sequence
|statement ';'
;
bracketsSeq:
LCB sequence RCB
;
brackOrStat:
bracketsSeq
|statement
;
statement:
assignmentStat
|ifStat
|whileStat
|
;
assignmentStat:
ID ':=' expression
ifStat:
IF LEFTPAR condition RIGHTPAR brackOrStat elsepart
;
elsepart:
ELSE brackOrStat
|
;
whileStat:
WHILE LEFTPAR condition RIGHTPAR brackOrStat
;
expression:
addOper expression
|expression addOper expression
|term
;
term:
term mulOper term
|factor
;
factor:
INT
|LEFTPAR expression RIGHTPAR
|ID
;
condition:
condition AND condition
|boolterm
;
boolterm:
boolterm OR boolterm
|boolfactor
;
boolfactor:
NOT LSB condition RSB
|LSB condition RSB
|expression relationalOper expression
;
relationalOper:
ISEQUAL
|LTHAN
|GTHAN
|NOTEQUAL
|LESSEQUAL
|GREATEREQUAL
;
addOper:
PLUS
|MINUS
;
mulOper:
MUL
|DIV
;
optionalSign
|addOper
;
%%
int main(int argc, char **argv)
{
extern FILE *yyin;
++argv, --argc; /* skip over program name */
if (argc > 0)
yyin = fopen(argv[0], "r");
else
yyin = stdin;
do
yyparse();
while(!feof(yyin));
}
Ma mise en œuvre de flex est assez simple où je reviens juste des jetons pour chaque symbole ou un identifiant nécessaire.
En utilisant ma mise en œuvre du programme simple:
program circuit
{
a:=b;
}
Je finissent par obtenir une erreur de syntaxe. Plus précisément lorsque l'analyse syntaxique atteint le point juste après :=
selon mes impressions de débogage J'utilise:
$ ./a.exe verilog.txt
text = program
text = circuit val = circuit
text = {
text = a val = a
text = :=
syntax error
C'est la première fois que je l'utilise flex et bison donc je devine que je fait une mauvaise mise en œuvre de ma grammaire originale à bisons depuis après la commande ./bison.exe -dy comp.y
je reçois:
conflits bison 64 changement/réduire
Toutes les idées seraient utiles. Merci!
Merde! J'ai oublié que j'ai déjà déclaré ': =' comme un jeton sur mon fichier lex. C'était mon erreur. Comme j'ai beaucoup de conflits, je construis ma grammaire dès le début et je la vérifie pas à pas en utilisant la commande -v. Merci pour vos commentaires utiles! :RÉ – fanulis