您好我使用lex和yacc来创建我自己的编程语言语法(排序),但无论我的语法规则如何放置,它都会在同一行第一行给出语法错误。
这是正则表达式的lex代码:
%{
#include <stdio.h>
#include "y.tab.h"
%}
%option noyywrap
punct [.]
virgula [,]
numar [0-9]+
numar2 [0-9]
%%
"&librarie=>" {return INCLUDE;}
"stringuri"|"vectori"|"mape"|"matematica" {return LIBRARII;}
"intreg"|"caracter"|"string"|"natural" {return TIPVAR;}
"real" {return REAL;}
"daca" {return DACA;}
"pentru" {return PENTRU;}
"cat_timp" {return CATTIMP;}
def_variabla_globala {return VARGLOBALE;}
def_variabla_locala {return VARLOCALE;}
structura_obiect {return STRUCTURA;}
"procedura[]" {return PROCEDURA;}
start_program {return START;}
stop_program {return STOP;}
inceput_bloc_if {return INBLOCIF;}
sfarsit_bloc_if {return SFBLOCIF;}
atunci {return ATUNCI;}
altfel {return ALTFEL;}
from {return FROM;}
to {return TO;}
smaller_than {return MAIMIC;}
greater_than {return MAIMARE;}
equal_to {return EGAL;}
different_than {return DIFERIT;}
inceput_bloc_for {return INBLOCFOR;}
sfarsit_bloc_for {return SFBLOCFOR;}
inceput_bloc_cat_timp {return INBLOCCATTIMP;}
sfarsit_bloc_cat_timp {return SFBLOCCATTIMP;}
executa {return EXECUTA;}
suma {return SUM;}
invers {return INV;}
oglindit {return OGL;}
"<-" {return ASIGNARE;}
[a-zA-Z][a-zA-Z0-9]* {return ID;REJECT;}
{numar} {return NUMAR;REJECT;}
[0-9]{punct}{numar} {return NUMARREAL;}
{numar}|({virgula}{numar})* {return VECTASIGN;}
({numar2}{punct}{numar})|({virgula}({numar2}{punct}{numar}))* {return VECTASIGNREAL;}
[a-zA-Z][a-zA-Z ]* {return CUVANT;REJECT;}
afisare {return AFISARE;}
[ \t] ;
\n {yylineno++;}
. {return yytext[0];}
%%
我在这两个正则表达式中使用了REJECT
,因为它给了我一个警告,我的一些规则相互冲突。
我的语法规则:
%{
#include <stdio.h>
extern FILE* yyin;
extern char* yytext;
extern int yylineno;
%}
%token INCLUDE LIBRARII ID TIPVAR CUVCHEIE REAL NUMARREAL FROM TO VECTASIGNREAL VARGLOBALE VARLOCALE VECTASIGN STRUCTURA PROCEDURA START STOP DACA PENTRU CATTIMP INBLOCIF SFBLOCIF ATUNCI ALTFEL MAIMIC MAIMARE EGAL DIFERIT INBLOCFOR SFBLOCFOR INBLOCCATTIMP SFBLOCCATTIMP EXECUTA SUM INV OGL ASIGNARE NUMAR CUVANT AFISARE
%start progr
%left '+' '-'
%left '*' '/'
%%
progr: headere declaratii program {printf("correct syntax");}
;
headere : header
|headere header
;
header : INCLUDE LIBRARII
;
declaratii : declaratie ';'
| declaratii declaratie ';'
;
declaratie : VARGLOBALE TIPVAR ID
| VARGLOBALE TIPVAR ID '[' NUMAR ']'
| VARGLOBALE TIPVAR ID ASIGNARE NUMAR
| VARGLOBALE TIPVAR ID ASIGNARE '#' CUVANT '#'
| VARGLOBALE TIPVAR ID '[' NUMAR ']' ASIGNARE '[' VECTASIGN ']'
| VARGLOBALE REAL ID
| VARGLOBALE REAL ID '[' NUMAR ']'
| VARGLOBALE REAL ID ASIGNARE NUMARREAL
| VARGLOBALE REAL ID '[' NUMAR ']' ASIGNARE '[' VECTASIGNREAL ']'
;
program : PROCEDURA START bloc STOP
;
bloc : declaratiile instructiuni
;
declaratiile : declaratia ';'
| declaratiile declaratia ';'
;
declaratia : VARLOCALE TIPVAR ID
| VARLOCALE TIPVAR ID '[' NUMAR ']'
| VARLOCALE TIPVAR ID ASIGNARE NUMAR
| VARLOCALE TIPVAR ID ASIGNARE '#' CUVANT '#'
| VARLOCALE TIPVAR ID '[' NUMAR ']' ASIGNARE '[' VECTASIGN ']'
| VARLOCALE REAL ID
| VARLOCALE REAL ID '[' NUMAR ']'
| VARLOCALE REAL ID ASIGNARE NUMARREAL
| VARLOCALE REAL ID '[' NUMAR ']' ASIGNARE '[' VECTASIGNREAL ']'
;
instructiuni : instructiune ';'
| instructiuni instructiune ';'
;
instructiune : instructiune_simpla ';'
| instructiune_compusa ';'
;
instructiune_simpla : ID ASIGNARE expresie ';'
;
expresie : expresie '+' expresie
| expresie '-' expresie
| expresie '*' expresie
| expresie '/' expresie
| functie
| NUMAR
| ID
;
functie : INV '(' expresie ')'
| SUM '(' expresie ',' expresie ',' expresie ',' expresie ',' expresie ')'
| OGL '(' expresie ')'
| AFISARE '(' NUMAR ')'
| AFISARE '(' ID ')'
| AFISARE '(' CUVANT ')'
;
instructiune_compusa : DACA conditie ATUNCI
INBLOCIF
instructiuni
SFBLOCIF
ALTFEL
INBLOCIF
instructiuni
SFBLOCIF
|PENTRU ID FROM NUMAR TO NUMAR EXECUTA
INBLOCFOR
instructiuni
SFBLOCFOR
|CATTIMP ID conditie NUMAR
INBLOCCATTIMP
instructiuni
SFBLOCCATTIMP
;
conditie : MAIMARE
| MAIMIC
| EGAL
;
%%
int yyerror(char * s){
printf("error: %s line:%d\n",s,yylineno);
}
int main(int argc, char** argv){
yyin=fopen(argv[1],"r");
yyparse();
}
这是我测试的文件,它应该返回程序具有正确的语法。
&librarie=>stringuri
&librarie=>vectori
def_variabila_globala intreg var1<-23;
def_variabila_globala natural vect[50]<-{1,3,51,2,421,12,43};
def_variabila_globala real a<-12.5;
def_variabila_globala caracter ch<-#x#;
def_variabila_globala string s<-#alabala portocala#;
structura_obiect persoana
~
real inaltime;
natural varsta;
~
procedura[]
start_program
def_variabila_locala intreg negativ,pozitiv,s,contor1,contor2<-5;
def_variabila_locala adunari_scaderi;
def_variabila_locala inmultiri_impartiri;
def_variabila_locala ad_scd_inm_imp;
persoana p1;
p1@inaltime<-1.82;
p1@varsta<-20;
adunari_scaderi<-243-12+43-12+11+31-124;
afisare<adunari_scaderi>;
inmultiri_impartiri<-3*4/2/2*3/9;
afisare<inmultiri_impartiri>;
ad_scd_inm_imp<-4*2-3+5/2*5;
afisare<ad_scd_inm_imp>;
negativ<-invers<2>;
afisare<negativ>;
daca(invers<inmultiri_impartiri> smaller_than 0)
antunci
inceput_bloc_if
pentru contor1 from 0 to 10 executa
inceput_bloc_for
afiseaza<#for1#>;
afiseaza<#for2#>;
sfarsit_bloc_for
sfarsit_bloc_if
altfel
inceput_bloc_if
afiseaza<#if#>;
sfarsit_bloc_if
cat_timp contor2 greater_than 0
inceput_bloc_cat_timp
afisare<#cattimp#>;
contor<-contor-1;
sfarsit_bloc_cat_timp
pozitiv<-invers<-2>;
afisare<pozitiv>;
var1<-oglindit<321>;
afisare<var1>;
s<-suma<1,3,12,31,oglindit<123-2>>;
afisare<s>;
afisare<#ProgramTerminat#>;
stop_program
我不知道哪里出错,是因为词汇规则,是否会互相干扰?
谢谢。
修改
错误消息:error: syntax error at line:1
确切的问题是解析器在我的文件中的"&librarie=>stringuri"
声明中看到了无效规则。 (第1行)