使用lex和yacc打印令牌
printing tokens using lex and yacc
我有一个lex文件,一个yacc文件和main.cpp文件。
我的main.cpp看起来像
int main(int argc, char **argv)
{
if (argc == 1)
{ int token;
curr_filename = "<stdin>";
yyin = stdin;
yyparse();
}
else
{
for (int i = 1; i < argc; ++i)
{
curr_filename = argv[i];
yyin = std::fopen(argv[i], "r");
if (yyin)
{
yyparse();
std::fclose(yyin);
}
else
{
utility::print_error(argv[i], "cannot be opened");
}
}
}
if (yynerrs > 0)
{
std::cerr << "Compilation halted due to lexical or syntax errors.n";
exit(1);
}
这有助于进行解析,但现在我想打印从lex文件生成的token。所以我通过调用yylex()对它做了一点修改,如下所示
int main(int argc, char **argv)
{
if (argc == 1)
{ int token;
curr_filename = "<stdin>";
yyin = stdin;
// calling yylex to get token
while(token= yylex())
{
switch(token){
case 258 :
std::cout << "class" ;
default :
std::cout << "token " ;
}
yyparse();
}
//rest of the code same
但是没有打印到输出。
如何在标准输出或文件
上打印令牌flex file
%option noyywrap
%option yylineno
%{
#include "flexbison.hpp"
#include "tokentable.hpp"
#include "symboltable.hpp"
#include "y.tab.h"
#include <stdio.h>
#define YY_USER_ACTION yylloc.first_line = yylloc.last_line = yylineno;
static const int MAX_STR_CONST = 1025;
char string_buf[MAX_STR_CONST]; // buffer to store string contstants encountered in source file
char *string_buf_ptr;
int num_comment = 0; // count to keep track how many opening comment tokens have been encountered
std::size_t curr_lineno = 0; // keep track of current line number of source file
bool str_too_long = false; // used to handle string constant size error check
%}
%x COMMENT
%x LINECOMMENT
%x STRING
DARROW =>
%%
"(*" {
BEGIN(COMMENT);
num_comment++;
}
"*)" {
if (num_comment <= 0) {
yylval.error_msg = "Unmatched *)";
return ERROR;
}
}
<COMMENT>"*)" {
num_comment--;
if (num_comment < 0) {
yylval.error_msg = "Unmatched *)";
return ERROR;
}
if (num_comment == 0) {
BEGIN(INITIAL);
}
}
<COMMENT>"(*" {
num_comment++;
}
<COMMENT>[^n] {
// eat everything within comments
}
<COMMENT>n {
++curr_lineno;
}
"--"[^n]* {
BEGIN(LINECOMMENT);
}
<LINECOMMENT>n {
++curr_lineno;
BEGIN(INITIAL);
}
<COMMENT><<EOF>> {
BEGIN(INITIAL);
yylval.error_msg = "EOF in comment";
return ERROR;
}
"=>" {
return DARROW;
}
(?i:class) {
return CLASS;
}
(?i:else) {
return ELSE;
}
(?i:in) {
return IN;
}
(?i:then) {
return THEN;
}
(?i:fi) {
return FI;
}
(?i:if) {
return IF;
}
(?i:inherits) {
return INHERITS;
}
(?i:let) {
return LET;
}
(?i:loop) {
return LOOP;
}
(?i:pool) {
return POOL;
}
(?i:while) {
return WHILE;
}
(?i:case) {
return CASE;
}
(?i:esac) {
return ESAC;
}
(?i:of) {
return OF;
}
(?i:new) {
return NEW;
}
(?i:isvoid) {
return ISVOID;
}
(?i:not) {
return NOT;
}
t(?i:rue) {
yylval.boolean = true;
return BOOL_CONST;
}
f(?i:alse) {
yylval.boolean = false;
return BOOL_CONST;
}
[0-9]+ {
yylval.symbol = inttable().add(yytext);
return INT_CONST;
}
"<=" {
return LE;
}
"<-" {
return ASSIGN;
}
[A-Z][a-zA-Z0-9_]* {
yylval.symbol = idtable().add(yytext);
return TYPEID;
}
[a-z][a-zA-Z0-9_]* {
yylval.symbol = idtable().add(yytext);
return OBJECTID;
}
";"|","|"{"|"}"|":"|"("|")"|"+"|"-"|"*"|"/"|"="|"~"|"<"|"."|"@" {
return *yytext;
}
n {
++curr_lineno;
}
[ frtv] {
// eat whitespace
}
/*
* String constants (C syntax)
* Escape sequence c is accepted for all characters c. Except for
* n t b f, the result is c.
*
*/
" {
BEGIN(STRING);
string_buf_ptr = string_buf;
memset(string_buf, 0, MAX_STR_CONST);
}
<STRING>" {
BEGIN(INITIAL);
yylval.symbol = stringtable().add(string_buf);
return STR_CONST;
}
<STRING>