b7d483a82bf0e673144215085a7050857e414020 — Michael Forney 3 months ago 3d8bad5
Fix line and column numbers of identifiers

The parser may need to read more tokens to determine the production rule,
so the lineno and colno counters from the lexer can't be used by the
parser to determine the location of an identifier.

Instead, change the tag of the CZ_IDENTIFIER token to strloc, and update
the lexer to store the lineno and colno values in it before they are
advanced.
2 files changed, 13 insertions(+), 18 deletions(-)

M lang.l
M lang.y
M lang.l => lang.l +8 -4
@@ 21,7 21,7 @@ #include "parse.h"
  #include "lang.tab.h"
  
- int lineno = 1, colno = 1;
+ static int lineno = 1, colno = 1;
  char *filename = "";
  const char *original_filename = "";
  struct source_file *current_source;


@@ 118,7 118,13 @@ "_float64x"			{ _lineno(); return CZ_DOUBLE; }
  "_ibm128"			{ _lineno(); return CZ_DOUBLE; }
  
- {L}{A}*				{ _lineno(); return check_type(); }
+ {L}{A}*				{
+ 	yylval.strloc.name = strdup(yytext);
+ 	yylval.strloc.lineno = lineno;
+ 	yylval.strloc.colno = colno;
+ 	_lineno();
+ 	return check_type();
+ }
  
  {HP}{H}+{IS}?				{ _lineno(); return CZ_CONSTANT; }
  {NZ}{D}*{IS}?				{ _lineno(); return CZ_CONSTANT; }


@@ 232,8 238,6 @@ }
  
  static int check_type(void) {
- 	yylval.sval = strdup(yytext);
- 
  	struct typedef_declaration *td = current_source->typedefs;
  	while (td) {
  		if (strcmp(td->name, yytext) == 0) {

M lang.y => lang.y +5 -14
@@ 9,7 9,6 @@ int yyerror(char *);
  int yylex(void);
  
- extern int lineno, colno;
  extern char *filename, *original_filename;
  %}
  


@@ 43,7 42,7 @@ %token CZ_LSHIFT_ASSIGN CZ_RSHIFT_ASSIGN
  %token CZ_BAND_ASSIGN CZ_BXOR_ASSIGN CZ_BOR_ASSIGN
  /* other tokens */
- %token<sval> CZ_IDENTIFIER
+ %token<strloc> CZ_IDENTIFIER
  %token CZ_CONSTANT
  %token<sval> CZ_STRING_LITERAL
  %token CZ_ELLIPSIS


@@ 83,11 82,7 @@ ;
  
  primary_expression
- 	: CZ_IDENTIFIER {
- 		$$.name = $1;
- 		$$.lineno = lineno;
- 		$$.colno = colno - strlen($$.name);
- 	}
+ 	: CZ_IDENTIFIER
  	| constant {
  		$$.name = NULL;
  	}


@@ 285,8 280,8 @@ struct typedef_declaration *td =
  					calloc(1, sizeof(struct typedef_declaration));
  				td->name = list->strloc.name;
- 				td->lineno = lineno;
- 				td->colno = colno;
+ 				td->lineno = list->strloc.lineno;
+ 				td->colno = list->strloc.colno;
  				td->next = current_source->typedefs;
  				current_source->typedefs = td;
  				next = list->next;


@@ 458,11 453,7 @@ ;
  
  direct_declarator
- 	: CZ_IDENTIFIER {
- 		$$.name = $1;
- 		$$.lineno = lineno;
- 		$$.colno = colno - strlen($$.name);
- 	}
+ 	: CZ_IDENTIFIER
  	| '(' declarator ')' {
  		$$ = $2;
  	}