help-bison
[Top][All Lists]
Advanced

[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
     **/
  }
;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]