[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Calling a parser from a parser
From: |
Tim Van Holder |
Subject: |
Re: Calling a parser from a parser |
Date: |
Tue, 26 Oct 2004 08:38:05 +0200 |
User-agent: |
Mozilla Thunderbird 0.8 (Windows/20040913) |
Antoine Fink wrote:
Hi,
Is it possible with Bison/Yacc to parse a language using 2 parsers for
different sections ?
Sure, I think it is, provided you don't need any lex state from before
the section (if you do, that /might/ make things harder).
What I would try is:
- assuming you have 2 languages, foo and bar, with 'bar' sections
within 'foo' sources, started with STARTBAR and ended with ENDBAR,
create a lexer and parser for both languages (foo.l/y and bar.l/y
for example) and make sure you specify different prefixes when
processing them
- in the 'bar' lexer and grammar, you'll need to handle the ENDBAR
token; if you require the 'bar' parser to also work standalone,
you may want to adjust the bar lexer to return some special initial
token when run from within foo so the grammar can allow ENDBAR only
when needed (and possibly also set a state so that ENDBAR is only
recognized by the lexer when needed).
- set up some system whereby the result of the bar parse can be easily
combined with the active foo parse results
- note: the suggestion below is untested; also, I'm pretty sure it isn't
thread-safe
Portions of the lexers and grammars:
=== foo.l ===
"STARTBAR" {
/* the grammar will invoke the bar parser, so set it up */
barrestart (yyin);
return t_STARTBAR;
}
=== foo.y ===
bar_section
: t_STARTBAR
{
bar_inside_foo = 1;
barparse();
/* TODO: integrate parse result */
}
;
=== bar.l ===
%s INSIDE_FOO
%%
{
if (bar_inside_foo) {
bar_inside_foo = 0;
BEGIN INSIDE_FOO;
return t_INSIDE_FOO;
}
}
<INSIDE_FOO>"ENDBAR" {
/* this is the end, so set up the foo lexer
to continue processing */
foorestart(yyin);
return t_ENDBAR;
}
=== bar.y ===
start
: normal_bar_parse
| t_INSIDE_FOO nested_bar_parse t_ENDBAR
{
/* TODO: - possibly discard $1
** - combine $2 and $3 for further use in the foo parser
**/
}
;