LINUX.ORG.RU

YYSTYPE Bison&Flex

 ,


0

2

Доброго времени суток, господа знатоки. Подскажите, пожалуйста, что я делаю не так. Черпаю информацию о Bison на сайте openNET. Нашёл информацию, что для того что по умолчанию все нетерминалы имеют тип int, мне нужно сменить тип на string. Пытался менять с помощью #define YYSTYPE std::string, но bison говорит всё равно что тип не определён. Ещё bison говорит что не знает какой тип у ‘;’,‘{’ и т.д., но если им приписать тип с помощью %type ‘;’, то он не воспринимает описанные мной действия. Я добился всякими обходными действиями что бы работало, но выводит не то что нужно.

В файле 2.txt лежит просто a = 2 , обычная переменная и int, а в консоль пишется два раза а.

Bison

%{
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
void yyerror(char const* msg);
extern FILE *yyin;
extern int yylineno;
extern int ch;
int yylex();

std::string outCode;

%}

%union{
	std::string*		stringVal;

}

%expect 3
%verbose
%token <stringVal> LTOE GTOE TILDEEQUAL DEQUAL DSLASH DLESS DGREATER DPOINT TPOINT
%token <stringVal> NOT NIL FALSE TRUE RETURN
%token <stringVal> OR AND WHILE REPEAT UNTIL IF THEN ELSE ELSEIF
%token <stringVal> FOR IN FUNCTION LOCAL DO END GOTO BREAK DCOLON
%token <stringVal> NAME ESCAPE STRING CHARSTRING COMMENT LINECOMMENT
%token	<stringVal> INT HEX FLOAT
%type	<stringVal> number var '.' '[' ']'



%left OR
%left AND
%left '<' '>' LTOE GTOE TILDEEQUAL DEQUAL
%left '|'
%left '~'
%left '&'
%left DLESS DGREATER
%right DPOINT
%left '+' '-'
%left '*' '/' '%' DSLASH
%left '#' NOT
%left UNARY
%right '^'

%start chunk

%%


chunk: block
;

block: statREP
		| statREP retstat
;

stat: 	';' 
		| varlist '=' explist
		| functioncall
		| COMMENT
		| LINECOMMENT
		| label
		| BREAK
		| GOTO NAME
		| DO block END
		| WHILE exp DO block END
		| REPEAT block UNTIL exp
		| IF exp THEN block elseifREP END
		| IF exp THEN block elseifREP ELSE block END
		| FOR NAME '=' exp ',' exp DO block END
		| FOR NAME '=' exp ',' exp ',' exp DO block END
		| FOR namelist IN explist DO block END
		| FUNCTION funcname funcbody
		| LOCAL FUNCTION NAME funcbody 
		| LOCAL attnamelist
		| LOCAL attnamelist '=' explist
;

statREP: /*empty*/ 
		| statREP stat 
;

elseifREP: /*empty*/ 
		| elseifREP ELSEIF exp THEN block
;

attnamelist: NAME attrib attnamelistREP
;

attnamelistREP: /*empty*/ 
		| attnamelistREP ',' NAME attrib
;

attrib: /*empty*/ 
		| '<' NAME '>' 
;

retstat: RETURN 
		| RETURN explist 
		| RETURN ';' 
		| RETURN explist ';'
;

label: DCOLON NAME DCOLON
;

funcname: NAME nameREP 
		| NAME nameREP ':' NAME
;

nameREP: /*empty*/ 
		| nameREP '.' NAME
;

varlist: var 
		|varlist ',' var
;

namelist: NAME 
		| namelist ',' NAME
;

explist: exp 
		| explist ',' exp
;

exp: NIL | FALSE | TRUE
		| number
		| string
		| TPOINT
		| functiondef
		| prefixexp
		| tableconstructor		
		| exp '^' exp		
		| NOT exp
		| '#' exp
		| '-' exp %prec UNARY
		| '~' exp %prec UNARY
		| exp '*' exp
		| exp '/' exp
		| exp '%' exp
		| exp DSLASH exp
		| exp '+' exp
		| exp '-' exp
		| exp DPOINT exp
		| exp '<' exp
		| exp '>' exp
		| exp LTOE exp
		| exp GTOE exp
		| exp TILDEEQUAL exp
		| exp DEQUAL exp
		| exp AND exp
		| exp OR exp
		| exp '&' exp
		| exp '|' exp
		| exp '~' exp
		| exp DLESS exp
		| exp DGREATER exp		
;

prefixexp_nf: var 
		| '(' exp ')'
;

prefixexp: prefixexp_nf 
		| functioncall
;

functionargs: args 
		| ':' NAME args
;

functioncall: prefixexp_nf functionargs 
		| functioncall functionargs
;

var
		: NAME { $<stringVal>$ = $1;std::cout << *($$) << std::endl;}
		| prefixexp '[' exp ']' { $<stringVal>$ = $<stringVal>1;}
		| prefixexp '.' NAME    { $<stringVal>$ = $<stringVal>1;}
;

args: '('/*empty*/')' 
		| '(' explist ')'
		| tableconstructor
		| string
;

functiondef: FUNCTION funcbody
;

funcbody: '('/*empty*/')' block END
		| '(' parlist ')' block END
;

parlist: namelist 
		| namelist ',' TPOINT
		| namelist TPOINT
;

tableconstructor: '{' '}'
		| '{' fieldlist '}'
;

fieldlist: field fieldlistREP
		| field fieldlistREP fieldsep
;

fieldlistREP: /*empty*/  
		| fieldlistREP fieldsep field
;

field: '[' exp ']' '=' exp 
		| NAME '=' exp 
		| exp
;

fieldsep: ',' | ';'
;

number
	: INT { std::cout << *($1) << std::endl;}
	| HEX 
	| FLOAT
;

string: STRING | CHARSTRING
;



%%
void yyerror(char const* msg) {}


int main() {

	yyin = fopen("2.txt", "r");
	yylineno = 1;
	ch = 1;
    if (yyparse() == 0) {
        cout << "Success" << endl;
    } else {
		cout << "Syntax error" << endl;
	}
	
	std::ofstream fout;
	fout.open("output code.txt");
	fout << outCode;
	fout.close();
	
    return 0;
}

Flex

%option noyywrap yylineno
%{
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include "lua.tab.h"
using namespace std;
void showError();
int ch;

%}

%%
[ \t\r\n]+ 					{ /* игнорируем пробелы, табы и переносы строк */ }

"("				{return 40;}
")"				{return 41;}
"["				{return 91;}
"]"				{return 93;}
"{"				{return 123;}
"}"				{return 125;}
"<"			   	{return 60;}
">"			   	{return 62;}
","				{return 44;}
"."				{return 46;}
"+"			   	{return 43;}
"-"			   	{return 45;}
"*"			   	{return 42;}
"/"			   	{return 47;}
"="			   	{return 61;}
":"			   	{return 58;}
";"			   	{return 59;}
"%"			   	{return 37;}
"&"			   	{return 38;}
"|"			   	{return 124;}
"~"			   	{return 126;}
"#"			   	{return 35;}
"^"			   	{return 94;}
["]			   	{return 34;}
"'"			   	{return 39;}
"\\"			{return 92;}

"<="			{yylval.stringVal = new std::string(yytext, yyleng); return (LTOE);}
">="			{yylval.stringVal = new std::string(yytext, yyleng); return (GTOE);}
"~="			{yylval.stringVal = new std::string(yytext, yyleng); return (TILDEEQUAL);}
"=="			{yylval.stringVal = new std::string(yytext, yyleng); return (DEQUAL);}
"//"			{yylval.stringVal = new std::string(yytext, yyleng); return (DSLASH);}
"<<"			{yylval.stringVal = new std::string(yytext, yyleng); return (DLESS);}
">>"			{yylval.stringVal = new std::string(yytext, yyleng); return (DGREATER);}
".."			{yylval.stringVal = new std::string(yytext, yyleng); return (DPOINT);}
"..."			{yylval.stringVal = new std::string(yytext, yyleng); return (TPOINT);}

"not"			{yylval.stringVal = new std::string(yytext, yyleng); return (NOT);}
"nil"			{yylval.stringVal = new std::string(yytext, yyleng); return (NIL);}
"false"			{yylval.stringVal = new std::string(yytext, yyleng); return (FALSE);}
"true"			{yylval.stringVal = new std::string(yytext, yyleng); return (TRUE);}
"return"		{yylval.stringVal = new std::string(yytext, yyleng); return (RETURN);}
"or"			{yylval.stringVal = new std::string(yytext, yyleng); return (OR);}
"and"			{yylval.stringVal = new std::string(yytext, yyleng); return (AND);}
"while"			{yylval.stringVal = new std::string(yytext, yyleng); return (WHILE);}
"repeat"		{yylval.stringVal = new std::string(yytext, yyleng); return (REPEAT);}
"until"			{yylval.stringVal = new std::string(yytext, yyleng); return (UNTIL);}
"if"			{yylval.stringVal = new std::string(yytext, yyleng); return (IF);}
"then"			{yylval.stringVal = new std::string(yytext, yyleng); return (THEN);}
"else"			{yylval.stringVal = new std::string(yytext, yyleng); return (ELSE);}
"elseif"		{yylval.stringVal = new std::string(yytext, yyleng); return (ELSEIF);}
"for"			{yylval.stringVal = new std::string(yytext, yyleng); return (FOR);}
"in"			{yylval.stringVal = new std::string(yytext, yyleng); return (IN);}
"function"		{yylval.stringVal = new std::string(yytext, yyleng); return (FUNCTION);}
"local"			{yylval.stringVal = new std::string(yytext, yyleng); return (LOCAL);}
"do"			{yylval.stringVal = new std::string(yytext, yyleng); return (DO);}
"end"			{yylval.stringVal = new std::string(yytext, yyleng); return (END);}
"goto"			{yylval.stringVal = new std::string(yytext, yyleng); return (GOTO);}
"break"			{yylval.stringVal = new std::string(yytext, yyleng); return (BREAK);}
"::"			{yylval.stringVal = new std::string(yytext, yyleng); return (DCOLON);}


[a-zA-Z_][a-zA-Z_0-9]* 		{yylval.stringVal = new std::string(yytext, yyleng); return (NAME);}
\"[ -~]*\"					{yylval.stringVal = new std::string(yytext, yyleng); return (STRING);}


[0-9]+						{return (INT);}
0[xX][0-9a-fA-F]+ 			{return (HEX);}
([0-9]*\.[0-9]+|[0-9]+\.)	{return (FLOAT);}

.      			{showError(); return 0;}
%%


void showError(){
    printf("Other input\n");
}

Пытался менять с помощью #define YYSTYPE std::string, но bison говорит всё равно что тип не определён.

Это надо делать повыше, где-то после первой %{.

Ещё bison говорит что не знает какой тип у ‘;’,‘{’ и т.д., но если им приписать тип с помощью %type ‘;’, то он не воспринимает описанные мной действия.

%type это для нетерминалов. Для ; и т.д. надо использовать %token.

xaizek ★★★★★ ()
Ответ на: комментарий от xaizek

Я пробовал писать #define YYSTYPE std::string как на примере ниже. Я объявил структуру и сказал что YYSTYPE теперь имеет тип MyClass, но bison при компиляции выдаёт мне ошибку. Хотя у меня есть работа предыдущего семестра, всё так же объявлено и работа рабочая, но тут работать не хочет

lua.y:184.33-34: выход за границы диапазона целого: `$1’

lua.y:185.25-26: $$ в `var’ не имеет описанного типа

lua.y:186.40-41: $$ в `var’ не имеет описанного типа


%{
#include <iostream>
#include <string>
#include <fstream>
#define YYSTYPE MyClass
using namespace std;
void yyerror(char const* msg);
extern FILE *yyin;
extern int yylineno;
extern int ch;
int yylex();
struct MyClass {std::string str};
std::string outCode;

%}



%union{
	std::string*		stringVal;

}

%expect 3
%verbose
%token <stringVal> LTOE GTOE TILDEEQUAL DEQUAL DSLASH DLESS DGREATER DPOINT TPOINT
%token <stringVal> NOT NIL FALSE TRUE RETURN
%token <stringVal> OR AND WHILE REPEAT UNTIL IF THEN ELSE ELSEIF
%token <stringVal> FOR IN FUNCTION LOCAL DO END GOTO BREAK DCOLON
%token <stringVal> NAME ESCAPE STRING CHARSTRING COMMENT LINECOMMENT
%token	<stringVal> INT HEX FLOAT




%left OR
%left AND
%left '<' '>' LTOE GTOE TILDEEQUAL DEQUAL
%left '|'
%left '~'
%left '&'
%left DLESS DGREATER
%right DPOINT
%left '+' '-'
%left '*' '/' '%' DSLASH
%left '#' NOT
%left UNARY
%right '^'

%start chunk

%%


chunk: block
;

block: statREP
		| statREP retstat
;

stat: 	';' 
		| varlist '=' explist
		| functioncall
		| COMMENT
		| LINECOMMENT
		| label
		| BREAK
		| GOTO NAME
		| DO block END
		| WHILE exp DO block END
		| REPEAT block UNTIL exp
		| IF exp THEN block elseifREP END
		| IF exp THEN block elseifREP ELSE block END
		| FOR NAME '=' exp ',' exp DO block END
		| FOR NAME '=' exp ',' exp ',' exp DO block END
		| FOR namelist IN explist DO block END
		| FUNCTION funcname funcbody
		| LOCAL FUNCTION NAME funcbody 
		| LOCAL attnamelist
		| LOCAL attnamelist '=' explist
;

statREP: /*empty*/ 
		| statREP stat 
;

elseifREP: /*empty*/ 
		| elseifREP ELSEIF exp THEN block
;

attnamelist: NAME attrib attnamelistREP
;

attnamelistREP: /*empty*/ 
		| attnamelistREP ',' NAME attrib
;

attrib: /*empty*/ 
		| '<' NAME '>' 
;

retstat: RETURN 
		| RETURN explist 
		| RETURN ';' 
		| RETURN explist ';'
;

label: DCOLON NAME DCOLON
;

funcname: NAME nameREP 
		| NAME nameREP ':' NAME
;

nameREP: /*empty*/ 
		| nameREP '.' NAME
;

varlist: var 
		|varlist ',' var
;

namelist: NAME 
		| namelist ',' NAME
;

explist: exp 
		| explist ',' exp
;

exp: NIL | FALSE | TRUE
		| number
		| string
		| TPOINT
		| functiondef
		| prefixexp
		| tableconstructor		
		| exp '^' exp		
		| NOT exp
		| '#' exp
		| '-' exp %prec UNARY
		| '~' exp %prec UNARY
		| exp '*' exp
		| exp '/' exp
		| exp '%' exp
		| exp DSLASH exp
		| exp '+' exp
		| exp '-' exp
		| exp DPOINT exp
		| exp '<' exp
		| exp '>' exp
		| exp LTOE exp
		| exp GTOE exp
		| exp TILDEEQUAL exp
		| exp DEQUAL exp
		| exp AND exp
		| exp OR exp
		| exp '&' exp
		| exp '|' exp
		| exp '~' exp
		| exp DLESS exp
		| exp DGREATER exp		
;

prefixexp_nf: var 
		| '(' exp ')'
;

prefixexp: prefixexp_nf 
		| functioncall
;

functionargs: args 
		| ':' NAME args
;

functioncall: prefixexp_nf functionargs 
		| functioncall functionargs
;

var
		: {extern e;
			e.str = $1;
			$$ = e;
			std::cout << $$.str;}
		| prefixexp '[' exp ']' 
		| prefixexp '.' NAME    
;

args: '('/*empty*/')' 
		| '(' explist ')'
		| tableconstructor
		| string
;

functiondef: FUNCTION funcbody
;

funcbody: '('/*empty*/')' block END
		| '(' parlist ')' block END
;

parlist: namelist 
		| namelist ',' TPOINT
		| namelist TPOINT
;

tableconstructor: '{' '}'
		| '{' fieldlist '}'
;

fieldlist: field fieldlistREP
		| field fieldlistREP fieldsep
;

fieldlistREP: /*empty*/  
		| fieldlistREP fieldsep field
;

field: '[' exp ']' '=' exp 
		| NAME '=' exp 
		| exp
;

fieldsep: ',' | ';'
;

number
	: INT 
	| HEX 
	| FLOAT
;

string: STRING | CHARSTRING
;



%%
void yyerror(char const* msg) {}


int main() {

	yyin = fopen("2.txt", "r");
	yylineno = 1;
	ch = 1;
    if (yyparse() == 0) {
        cout << "Success" << endl;
    } else {
		cout << "Syntax error" << endl;
	}
	
	std::ofstream fout;
	fout.open("output code.txt");
	fout << outCode;
	fout.close();
	
    return 0;
}

Работа прошлого семестра

%{
#include <iostream>
#include <string>
#define YYSTYPE express
using namespace std;
void yyerror(char const* msg);
int yylex();
struct express{int position; string str;};
%}

%%
S: E	{cout << $$.str;}
;
E: E '+' T	{
	express ex; 
	ex.str = $1.str + "+" + $3.str;
	ex.position = 1; $$ = ex}	|	T	{$$ = $1;}
;
T: T '*' F	{
	express ex;
	ex.position = 2;
	if($1.position == 1) ex.str = "(" + $1.str + ")";
	else ex.str = $1.str;
	ex.str =  ex.str  + "*";
	if($3.position == 1) ex.str = ex.str + "(" + $3.str + ")";
	else ex.str = ex.str + $3.str;
	$$ = ex;}	|	F	{$$ = $1;}
;
F: 'a'	{
	express ex;
    ex.str = "a";
    ex.position = 0; 
	$$ = ex;
	std::cout << *($$)}
;
F: 'b'  {
	express ex;
    ex.str = "b";
    ex.position = 0; 
	$$ = ex;}
;
F: '(' E ')' {$$ = $2;}
;
%%

void yyerror(char const* msg) {}

int yylex() {
	char c;
	if(!std::cin.get(c)) return 0;
	if(c == '\n') return 0;
	return c;
}

int main() {

    if (yyparse() == 0) {
        cout << "\nSuccess\n";
    } else {
		cout << "\nSyntax error\n";
	}

    return 0;
}
LSTSnaiper ()
Ответ на: комментарий от xaizek

Я попробовал убрать union, то взамен получил 3 вида ошибок

Первая

lua.y: In function ‘int yyparse()’:

lua.y:178:13: error: ‘e’ does not name a type

178 | : NAME {extern e;e.str = $1;$$ = e;std::cout << $$.str;}

Вторая

flexdoc.l: In function ‘int yylex()’:

flexdoc.l:43:9: error: request for member ‘stringVal’ in ‘yylval’, which is of non-class type ‘YYSTYPE’ {aka ‘int’}

43 | «<=» {yylval.stringVal = new std::string(yytext, yyleng); return (LTOE);}

Третья

lua.y:12:29: error: expected ‘;’ at end of member declaration

12 | struct MyClass {std::string str};

LSTSnaiper ()
Ответ на: комментарий от LSTSnaiper

error: ‘e’ does not name a type

Аноним же говорил, что там код бредовый. extern e -> MyClass e.

struct MyClass {std::string str};

; перед } кто будет ставить?

error: request for member ‘stringVal’ in ‘yylval’, which is of non-class type ‘YYSTYPE’ {aka ‘int’}

Лексеру тоже надо этот же тип указать.

Ещё <stringVal> у %token можно повыкидывать, он тоже мешать умеет (предполагает %union, вроде).

xaizek ★★★★★ ()
Ответ на: комментарий от xaizek

Да, я повыкидывал, просто не стал перезаливать код. Осталось понять только как указать лексеру… с union- то уже отработанная схема. Чёт я не внимательный…

LSTSnaiper ()
Последнее исправление: LSTSnaiper (всего исправлений: 1)
Ответ на: комментарий от LSTSnaiper

Да также оно указывается, через #define YYSTYPE. Оно может и само подхватиться от bison, но так не всегда.

В Интернете должно быть куча примеров, а на bison и flex есть подробная официальная документация, там всё это можно найти (включая простые примеры).

xaizek ★★★★★ ()
Ответ на: комментарий от xaizek

У меня получился вот такой lex файл

%option noyywrap yylineno
%{
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include "lua.tab.h"
using namespace std;
void showError();
int ch;
%}

%%
"\n"			{ch = 1;}
[ \t\r]+ 		{ /* игнорируем пробелы, табы и переносы строк */ }

"("				{printf("DELIM (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return 40;}
")"				{printf("DELIM (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return 41;}
"["				{printf("DELIM (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return 91;}
"]"				{printf("DELIM (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return 93;}
"{"				{printf("DELIM (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return 123;}
"}"				{printf("DELIM (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return 125;}
"<"			   	{printf("OPERATION (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return 60;}
">"			   	{printf("OPERATION (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return 62;}
","				{printf("DELIM (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return 44;}
"."				{printf("DELIM (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return 46;}
"+"			   	{printf("OPERATION (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return 43;}
"-"			   	{printf("OPERATION (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return 45;}
"*"			   	{printf("OPERATION (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return 42;}
"/"			   	{printf("OPERATION (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return 47;}
"="			   	{printf("OPERATION (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return 61;}
":"			   	{printf("DELIM (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return 58;}
";"			   	{printf("DELIM (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return 59;}
"%"			   	{printf("OPERATION (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return 37;}
"&"			   	{printf("OPERATION (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return 38;}
"|"			   	{printf("OPERATION (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return 124;}
"~"			   	{printf("OPERATION (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return 126;}
"#"			   	{printf("OPERATION (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return 35;}
"^"			   	{printf("OPERATION (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return 94;}
["]			   	{printf("DELIM (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return 34;}
"'"			   	{printf("DELIM (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return 39;}
"\\"			{printf("DELIM (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return 92;}

"<="			{printf("OPERATION (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (LTOE);}
">="			{printf("OPERATION (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (GTOE);}
"~="			{printf("OPERATION (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (TILDEEQUAL);}
"=="			{printf("OPERATION (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (DEQUAL);}
"//"			{printf("OPERATION (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (DSLASH);}
"<<"			{printf("OPERATION (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (DLESS);}
">>"			{printf("OPERATION (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (DGREATER);}
".."			{printf("OPERATION (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (DPOINT);}
"..."			{printf("OPERATION (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (TPOINT);}

"not"			{printf("KEYWORD (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (NOT);}
"nil"			{printf("KEYWORD (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (NIL);}
"false"			{printf("KEYWORD (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (FALSE);}
"true"			{printf("KEYWORD (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (TRUE);}
"return"		{printf("KEYWORD (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (RETURN);}
"or"			{printf("KEYWORD (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (OR);}
"and"			{printf("KEYWORD (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (AND);}
"while"			{printf("KEYWORD (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (WHILE);}
"repeat"		{printf("KEYWORD (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (REPEAT);}
"until"			{printf("KEYWORD (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (UNTIL);}
"if"			{printf("KEYWORD (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (IF);}
"then"			{printf("KEYWORD (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (THEN);}
"else"			{printf("KEYWORD (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (ELSE);}
"elseif"		{printf("KEYWORD (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (ELSEIF);}
"for"			{printf("KEYWORD (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (FOR);}
"in"			{printf("KEYWORD (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (IN);}
"function"		{printf("KEYWORD (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (FUNCTION);}
"local"			{printf("KEYWORD (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (LOCAL);}
"do"			{printf("KEYWORD (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (DO);}
"end"			{printf("KEYWORD (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (END);}
"goto"			{printf("KEYWORD (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (GOTO);}
"break"			{printf("KEYWORD (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (BREAK);}
"::"			{printf("KEYWORD (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (DCOLON);}

[a-zA-Z_][a-zA-Z_0-9]* 		{printf("IDENTIFIER (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (NAME);}
\".*\" 						{printf("STRING (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (STRING);}
\'.*\'                		{printf("STRING (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (CHARSTRING);}
"--".*\n?					{printf("LINECOMMENT (%d, %d)\n", yylineno, ch); ch += yyleng; return (LINECOMMENT);}

[0-9]+						{printf("NUMBER (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (INT);}
0[xX][0-9a-fA-F]+ 			{printf("NUMBER (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (HEX);}
([0-9]*\.[0-9]+|[0-9]+\.)	{printf("NUMBER (%d, %d): %s\n", yylineno, ch, yytext); ch += yyleng; return (FLOAT);}

.      			{showError();}
%%

void showError(){
	printf("Lexical error in line: %d, char: %d.\n", yylineno, ch+1);
}

У меня теперь появился вопрос как мне вернуть из лексера не только токен, но и значение, которое хранит этот токен? Может есть какая специальная функция у bison для этого?

LSTSnaiper ()
Ответ на: комментарий от xaizek

Не помогает для чего? Я просто забыл что уже давно этот лексер переписал и использовал старую версию лексера, потому что уже столько файлов похожих друг на друга что не понятно где истинный)

LSTSnaiper ()