| |
oziphantom
Registered: Oct 2014 Posts: 490 |
Anybody know Bison/Yacc?
I want to extend the VICE monitor to be able to look up an address in a "bank" on a break.. so something like
break $1234 IF @IO:D010 & $40 = $40 where @IO:D010 looks up the VIC register D010 and get its value.
CMD_BANK BANKNAME end_cmd
{ mon_bank(e_default_space, $2); } seems to be the C you can use to change the banks
int monbank = mon_interfaces[mem]->current_bank;/code] seems like it would allow you to save the current bank. And
MEMSPACE src_mem = addr_memspace(start_addr);
WORD start = addr_location(start_addr);
byte1 = mon_get_mem_val(src_mem, start)); could be used to look up the value, its just a matter of putting it all together in a yacc file to glue it together and make it work as part of the condition_expression, so if somebody could help me with the yacc modifications I would greatly appreciate it ;)
For completeness it probably needs to be C: only and making it take the form @C:(bank):Addr to make it clear might be best.. |
|
| |
knue
Registered: Dec 2012 Posts: 37 |
yes, I know yacc/bison. It's been a while though and I highly recommend anyone who wants to write a parser to *not* use these tools. Anyway, what do you want to know? |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
Quote:I highly recommend anyone who wants to write a parser to *not* use these tools.
*grin* |
| |
iAN CooG
Registered: May 2002 Posts: 3193 |
knue: good, find a better solution, and post to vice@sourceforge the changes for vice monitor.
(yes, I'm ironic) |
| |
oziphantom
Registered: Oct 2014 Posts: 490 |
How to modify this https://sourceforge.net/p/vice-emu/code/HEAD/tree/trunk/vice/sr.. file.
Such that the
cond_expr: cond_expr COMPARE_OP cond_expr
{
$$ = new_cond; $$->is_parenthized = FALSE;
$$->child1 = $1; $$->child2 = $3; $$->operation = $2;
}
| cond_expr COMPARE_OP error
{ return ERR_INCOMPLETE_COMPARE_OP; }
| L_PAREN cond_expr R_PAREN
{ $$ = $2; $$->is_parenthized = TRUE; }
| L_PAREN cond_expr error
{ return ERR_MISSING_CLOSE_PAREN; }
| compare_operand
{ $$ = $1; }
;
compare_operand: register { $$ = new_cond;
$$->operation = e_INV;
$$->is_parenthized = FALSE;
$$->reg_num = $1; $$->is_reg = TRUE;
$$->child1 = NULL; $$->child2 = NULL;
}
| number { $$ = new_cond;
$$->operation = e_INV;
$$->is_parenthized = FALSE;
$$->value = $1; $$->is_reg = FALSE;
$$->child1 = NULL; $$->child2 = NULL;
}
;
can also handle having something of the form @C:BANKNAME:ADDR handled as one of the "rules" at the moment it handles a register such that it is .A .X .Y .SP and a number $1000, I don't need to "C" code part done, just the yacc part ;)
Allowing the user the form a monitor command such as
break $4000 IF @C:IO:D500 != $3e at the moment it handles break $4000 IF .A != $40 |
| |
Compyx
Registered: Jan 2005 Posts: 631 |
I have to agree with knue, bison/yuck is horrible. Keeps me from doing any serious work on the monitor. As with most GNU stuff, this sort of stuff worked in the 70's when memory and storage space where very valuable. Not so much now. |
| |
knue
Registered: Dec 2012 Posts: 37 |
ok, this is what you have to do.
In mon_parse.y you need to add sth like this:
compare_operand: register { $$ = new_cond;
$$->operation = e_INV;
$$->is_parenthized = FALSE;
$$->reg_num = $1; $$->is_reg = TRUE;
$$->child1 = NULL; $$->child2 = NULL;
}
| number { $$ = new_cond;
$$->operation = e_INV;
$$->is_parenthized = FALSE;
$$->value = $1; $$->is_reg = FALSE;
$$->child1 = NULL; $$->child2 = NULL;
}
| '@' BANKNAME ':' number {
$$ = new_cond;
$$->operation = e_INV;
$$->is_parenthized = FALSE;
$$->bankname = $2; $$->value = $4; $$->is_reg = FALSE;
$$->child1 = NULL; $$->child2 = NULL;
}
;
Of course, you'll add a another field bankname to cond_node_s in montypes.h.
Be careful to not read garbage data when you read from this field. All other parts of the code which construct this thing must initialize this field with some default value. Check:
%type<cond_node> opt_if_cond_expr cond_expr compare_operand
Here you can see, which rules create a cond_node and need to initialize this new field.
ah, this code uses the syntax:
@bankname:number |
| |
knue
Registered: Dec 2012 Posts: 37 |
speaking of cond_node_s. you can probably put value and reg_num in a union. |
| |
Count Zero
Registered: Jan 2003 Posts: 1932 |
Phew - thx knue and ozi for going for this. My last small changes on that yacc shice broke a few things and had to be reverted :)
That feature addition would rock a lot! |
| |
oziphantom
Registered: Oct 2014 Posts: 490 |
ERROR -- Unexpected token:
break c253 if @io:$d020 == 0
^
Doesn't like it, I tried adding spaces, no difference
Where banks are defined asAvailable banks (some may be equivalent to others):
default *cpu ram rom io ram1 intfunc extfunc cart c64rom vdc |
| |
oziphantom
Registered: Oct 2014 Posts: 490 |
maybe the lex file needs some modifications? |
| |
knue
Registered: Dec 2012 Posts: 37 |
So these are the important bits in the mon_lex.l:
%{
if (new_cmd) {
if (!(asm_mode && opt_asm)) {
last_len = cur_len = 0;
}
if (asm_mode) {
BEGIN (ASM_MODE);
opt_asm = 0;
} else {
BEGIN (CMD);
}
new_cmd = 0;
}
%}
<CMD>{
//...
bank { BEGIN(BNAME); return CMD_BANK; }
//...
}
//...
<BNAME>[_a-zA-Z0-9]* { yylval.str = lib_stralloc(yytext); return BANKNAME; }
So, lex is more powerful than just simple regular expressions. Additionally, you can define states. Simple example would be nested comments. Sth you couldn't do with straight regular expressions. Those <FOO> are the states. Read the code as follows:
When we are about to lex a new command that is *not* in asm_mode we begin CMD state.
Then, *only* if we are in CMD mode, lexing 'bank' starts BNAME mode. And only *then* we lex any string as BANKNAME. So this is the only occasion where yacc actually sees the BANKNAME token.
What we would have to do is to add a lex rule which additionally lexes a string as BANKNAME. A simple rule like:
§[_a-zA-Z0-9]* { yylval.str = lib_stralloc(yytext); return BANKNAME; }
would do the trick. Then, §io would be a BANKNAME token. BTW you can also change the parser to just recognize:
BANKAME ':' number
or even just
BANKNAME number
instead of
'@' BANKNAME ':' number
because '§' is now part of the BANKNAME token. |
| |
oziphantom
Registered: Oct 2014 Posts: 490 |
add '§' to the bankname would be bad, as then the char* to bank number functions won't recognise the string, it won't match.. doing a straight ++ on it to skip a char is kind of evil and will probably fail on some system somewhere.
SO I just put [_a-zA-Z0-0]* {yylval.str= lib_stralloc(yytext); return BANKNAME; } at the bottom of <COND_MODE>{ AND IT WORKS!!!
now onwards to getting labels to work :) |
| |
oziphantom
Registered: Oct 2014 Posts: 490 |
and now labels work |
| |
knue
Registered: Dec 2012 Posts: 37 |
ah, there is even a COND_MODE. I missed that. Sort of bad to work with that many states in the lexer. Would be better to have that logic in the parser... |
| |
Count Zero
Registered: Jan 2003 Posts: 1932 |
How is this progressing? Patch upcoming for "upstream"? :) |