Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[C/lex/yacc] Line nummer klopt niet

Pagina: 1
Acties:

  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 16-09 20:30
Ik heb een een lex/yacc parser in C (onder solaris) welke een linenummer bij houdt.
Deze leest een lijst met naam, nummer in voor instellingen:

vb:
code:
1
2
3
AA 1
TEST 2
IKKE 3


Er kan ook commentaar gebruikt worden:
code:
1
2
3
4
5
AA 1 # instellingen van 'AA'
TEST 2

# test commentaar
IKKE 3


Tijdens het parser wil ik het commentaar van dezelfde regel weten, dus van AA -> "instellingen van 'AA'"
Dit doe ik door regelnummers bij te houden: na het parsen van een instellingen wordt een variabele met het laatste regelnummer geupdate emt yylineno. Zodra er een stuk commentaar gelezen wordt wordt de huidige met de laatste vergeleken, indien hetzelfde is het op dezelfde regel.

Echter haalt lex de whitespaces weg:
WHITESPACE [ \t\f\b\r\n]+
(en gaan naar /dev/null ;) )

Als ik de file van hierboven inleest, blijkt dat 'TEST 2' op regel 4 staat, ipv 2. Deze wordt dus bij het volgende stukje geplakt. Het commentaar staat ook op regel 4, dus worden deze gekoppelt.

Hoe kan ik er voor zorgen dat 'TEST 2' als regel 2 verschijnt en niet als de regel met de volgende installingen/commentaar?

if broken it is, fix it you should


  • VyperX
  • Registratie: Juni 2001
  • Laatst online: 12-11 16:48
Ik denk dat je er in dat geval toch niet aan ontkomt om newlines toch een betekenis te geven. :)
Oftewel, een NEWLINE token wat als actie alleen een (externe?) newline counter ophoogt, maar verder niet aan Yacc wordt gemeld.

Edit: sowieso heeft een newline wel betekenis bij jou, het is namelijk het einde van een commentaar regel.

[ Voor 19% gewijzigd door VyperX op 14-07-2010 11:31 ]

My Dwarf Fortress ASCII Reward: ~~@~~####,.".D",.B""


  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 16-09 20:30
VyperX schreef op woensdag 14 juli 2010 @ 11:26:
Ik denk dat je er in dat geval toch niet aan ontkomt om newlines toch een betekenis te geven. :)
Oftewel, een NEWLINE token wat als actie alleen een (externe?) newline counter ophoogt, maar verder niet aan Yacc wordt gemeld.

Edit: sowieso heeft een newline wel betekenis bij jou, het is namelijk het einde van een commentaar regel.
Newline als commentaar doet lex voor mij:
COMMENT #.*

Probleem is dat ik (in sommige gevallen) ook meerdere instelleingen op 1 regel wil hebben:
code:
1
TEST 1 IKKE 3

if broken it is, fix it you should


  • VyperX
  • Registratie: Juni 2001
  • Laatst online: 12-11 16:48
Misschien kan je analoog naar je comment rule ook een 'empty line' rule kan toevoegen?
code:
1
EMPTYLINE [ \t\f\b]*\n


Edit: Ik blijf er alsnog bij dat Flex gewoon alle newlines moet afvangen (en deze gewoon niet als tokens returnen naar Yacc).

[ Voor 33% gewijzigd door VyperX op 14-07-2010 12:02 ]

My Dwarf Fortress ASCII Reward: ~~@~~####,.".D",.B""


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 20:54

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik snap het niet helemaal. Linenummers zijn als het goed is gewoon gekoppeld aan het token. Dus tenzij jij iets als "TEST 1\n\n\n" als 1 token ziet kun je gewoon het juiste regelnummer voor 'TEST' gebruiken.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 16-09 20:30
VyperX schreef op woensdag 14 juli 2010 @ 11:53:
Misschien kan je analoog naar je comment rule ook een 'empty line' rule kan toevoegen?
code:
1
EMPTYLINE [ \t\f\b]*\n


Edit: Ik blijf er alsnog bij dat Flex gewoon alle newlines moet afvangen (en deze gewoon niet als tokens returnen naar Yacc).
Ja, dat doet ie al: (deel van lex)
code:
1
2
WHITESPACE      [ \t\f\b\r\n]+
{WHITESPACE}    ;


Wat resulteert wat oisyn zegt:
'TEST\n\n\n' wordt als 'TEST' naar yacc gestuurd, alleen wel met 3 \n's teveel waardoor het linennummer niet klopt.
Ik wil dus als ik in lex het line nummer (yylineno) opvraag, de regel krijgt waar TEST begon (en niet waar die eindigde). Echter weet ik niet hoe ik dat moet oplossen. Mijn aanname was dat lex de lineno's goed bijwerkte en dat ik deze gewoon op kon vragen. De newlines wil ik NIET als token doorsturen, maar het lijkt erop dat ik dat wel moet gaan doen.

if broken it is, fix it you should


  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 16-09 20:30
.oisyn schreef op woensdag 14 juli 2010 @ 12:03:
Ik snap het niet helemaal. Linenummers zijn als het goed is gewoon gekoppeld aan het token. Dus tenzij jij iets als "TEST 1\n\n\n" als 1 token ziet kun je gewoon het juiste regelnummer voor 'TEST' gebruiken.
En wat is het regel nummer voor 'TEST'?

if broken it is, fix it you should


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 20:54

.oisyn

Moderator Devschuur®

Demotivational Speaker

elgringo schreef op woensdag 14 juli 2010 @ 13:08:
Wat resulteert wat oisyn zegt:
'TEST\n\n\n' wordt als 'TEST' naar yacc gestuurd, alleen wel met 3 \n's teveel waardoor het linennummer niet klopt.
Dat klopt dus niet. Die enters zijn geen onderdeel van het token, en dus moet hij het regelnummer er ook niet bij gebruiken.
Ik wil dus als ik in lex het line nummer (yylineno) opvraag, de regel krijgt waar TEST begon (en niet waar die eindigde).
Als jouw productieregel iets is als
code:
1
"TEST" { /* doe hier iets met yylineno */ }

dan zou het imho moeten kloppen. Eens even kijken hoe ik dat opgelost heb destijds.

.edit: hmm wacht, er staat me iets van bij dat lex (of iig flex, die gebruikte ik altijd) ook zelf geheel automatisch het begin en eind (dus regel en kolom) van iedere token automatisch kon doorsturen in de token struct)

.edit2: jammer, mijn internet thuis lijkt eruit te liggen, ik kan nu niet bij m'n code :)

[ Voor 18% gewijzigd door .oisyn op 14-07-2010 13:33 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 16-09 20:30
.oisyn schreef op woensdag 14 juli 2010 @ 13:23:
[...]

Dat klopt dus niet. Die enters zijn geen onderdeel van het token, en dus moet hij het regelnummer er ook niet bij gebruiken.


[...]

Als jouw productieregel iets is als
code:
1
"TEST" { /* doe hier iets met yylineno */ }

dan zou het imho moeten kloppen. Eens even kijken hoe ik dat opgelost heb destijds.

.edit: hmm wacht, er staat me iets van bij dat lex (of iig flex, die gebruikte ik altijd) ook zelf geheel automatisch het begin en eind (dus regel en kolom) van iedere token automatisch kon doorsturen in de token struct)
en waar vind ik dat token struct?

de newlines zijn geen onderdeel van het token, maar ook niet van het volgende token. Toch moeten de linenummers bijgewerkt worden. En nu worden de newlines achter een token meegenomen (en dat wil ik dus niet)

if broken it is, fix it you should


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 20:54

.oisyn

Moderator Devschuur®

Demotivational Speaker

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 16-09 20:30
Als ik:
code:
1
extern YYLTYPE  yylloc;
aan mijn lex toe voeg, krijg ik een compile fout dat hij yylloc niet kan referencen. Wat doe ik fout?

if broken it is, fix it you should


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 20:54

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ja kom nou, ga eens wat documentatie doorlezen. Ik weet het ook niet uit mijn hoofd :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 16-09 20:30
Dat ik ik de hele dag al :z :(

Anyway, ik heb yyloc bereikt, gevonden en deze werkt. Echter moet hier zinvolle data in komen.
Ik heb geprobeerd bij een newline de first_line te verhogen. Om een of andere reden worden regels met alleen whitespace overgeslagen en verscheiden 2 token die in het bestand op 2 regels staan, dezelfde first_line te hebben.

Ik heb ook met de define geprobeerd:
code:
1
#define YY_USER_INIT yylloc.first_line = yylineno;

In dat geval blijft ie altijd 1.

EDIT: Schiet mij maar lek.....
Ik had 2 token waar die matchte met '\n' waardoor het niet werktee. Deze heb ik afgeschoten en nu gaat het goed.

[ Voor 12% gewijzigd door elgringo op 14-07-2010 15:15 ]

if broken it is, fix it you should

Pagina: 1