Related articles |
---|
How to handle comment using lex/yacc? cylin@avant.com.tw (cylin) (2004-01-09) |
Re: How to handle comment using lex/yacc? a7244270@yahoo.com (2004-01-16) |
From: | "cylin" <cylin@avant.com.tw> |
Newsgroups: | comp.compilers |
Date: | 9 Jan 2004 23:43:23 -0500 |
Organization: | Compilers Central |
Keywords: | parse, question, comment |
Posted-Date: | 09 Jan 2004 23:43:23 EST |
Dear all,
I have a statement like this:
SLICE#IDN,SLCODE[,WIDTH=w][,REFLECT=r][COMMENTS]
Where:
SLICE the command name.
# one space or tab.
SLCODE integer
w real
r real
COMMENT user-specified text. Any legal characters are permited.
Comments must not inlucde WIDTH= or REFLECT=
A text file that there are 2 lines like this:
SLICE 4k,20,WIDTH=3.0,REFLECT=5.0 xxxxxxxxxxxxxxxxxxxx
SLICE 4k,20,WIDTH=3.0,REFLECT=5.0 xxxxxxxxxxxxxxxxxxxx
When I parse this text file,the first line always is right,
but the second line ayways gets syntax error.
How to fix my lex and yacc file?? Thx.
There is a way to comment, but used for other command name.
When exceeding N characters begin from a line, the text after N is comment.
How to do that?? Thanks for your help.
lex file:
----------------------------------------------------------------------------
---------
%{
#include <stdio.h>
#include "y.tab.h"
char linebuf[200];
char ch;
int i;
int yylineno;
%}
white [ \t]+
digit [0-9]
integer -?{digit}+
exponent [eE][-+]?{digit}+
real -?({digit}+|({digit}*\.{digit}+){exponent}?)
letter [a-zA-Z]
text (-?{digit}*{letter}+-?{digit}*)|({letter}+-?{digit}+{letter}*)
punctuation [,=]
%x stSLICE
%%
{white} ;
{integer} {yylval.integer=atoi(yytext);printf("%d integer in
lex\n",atoi(yytext));return INTEGER;}
{real} {yylval.real=atof(yytext);printf("%g real in
lex\n",atof(yytext));return REAL;}
{punctuation} {return yytext[0];}
SLICE {BEGIN stSLICE;return SLICE;}
<stSLICE>{text} {BEGIN INITIAL;return STRING;}
WIDTH {return WIDTH;}
REFLECT {return REFLECT;}
\n.* {yylineno++;strcpy(linebuf,yytext+1);yyless(1);}
. ;
%%
int myinput(void) {return input();}
void myunput(char c) {unput(c);}
----------------------------------------------------------------------------
---------
yacc file:
----------------------------------------------------------------------------
---------
%{
#include <stdio.h>
%}
%union {
char* string;
int integer;
float real;
}
%token SLICE WIDTH REFLECT
%token <integer> INTEGER
%token <real> REAL
%token <string> STRING
%type <real> number
%%
top_rule:
| slice_rule {ignoreComment('\n');}
;
slice_rule: slice_base
| slice_base slice_option_list
;
slice_base: SLICE user_defined_text ',' INTEGER {printf("In yacc
SLICE:,slice code=%d\n",$4);}
;
slice_option_list: slice_option
| slice_option_list slice_option
;
slice_option: width_rule
| reflect_rule
;
width_rule: ',' WIDTH '=' number {printf("WIDTH=%g\n",$4);}
;
reflect_rule: ',' REFLECT '=' number {printf("REFLECT=%g\n",$4);}
;
number: INTEGER {$$=(float)($1);}
| REAL {$$=$1;}
;
user_defined_text: STRING | INTEGER
;
%%
extern FILE *yyin;
extern char *yytext;
extern int yylineno;
extern int yyinput(void);
extern char linebuf[200];
int main(int argc,char** argv)
{
yylineno=0;
yyin=fopen(argv[1],"r");
if (yyin) {
while(!feof(yyin)) {
yyparse();
}
fclose(yyin);
return 0;
}
else {
return -1;
}
}
yyerror(char* errmsg)
{
fprintf(stderr,"%d: %s at %s this
line:\n%s\n",yylineno,errmsg,yytext,linebuf);
}
void ignoreComment(char cDelimiter)
{
char ch;
for(;;) {
ch=myinput();
if (ch==cDelimiter) {
if (cDelimiter=='\n') {
myunput(cDelimiter);
}
break;
}
}
}
[Yuck, what an unpleasant syntax. In response to your specific question
about lines the pattern \n.* slurps up the second and all subsequent
lines, so that's probably not what you want. -John]
Return to the
comp.compilers page.
Search the
comp.compilers archives again.