Re: How do I return more than one tag from production?

Eric Ludlam <[email protected]> Sat, 20 Feb 2016 09:04:27 -0500
Newsgroups gmane.emacs.semantic
Message-ID <[email protected]>
On 02/19/2016 01:36 PM, Gracjan Polak wrote:
> Hi all,
>
> Due to how reparsing interacts with Haskell block structure it may
> happen that after reparsing a block that had one function definition now
> will two of those. For example, before:
>
> f = x
>    where
>      z = w
>      k = p
>
> After edit:
>
> f = x
>    where
>      z = w
> k = p
>
> So now there are two functions (f and k), but only one block is
> reparsed. How to create a rule that covers this case?

Hi Gracjan,

You have a lot of questions that didn't get answered, so I'm not sure 
where you are at this time, so I'll try to cover a few things.  I'll use 
C as an example since that is what I'm most familiar with.

In C, if you have a code snippet such as:

int a;

int b;

int c;

and you change "int b" into "int bob", the incremental parser will find 
the full extents of the previous tag "int b" which were laid out with 
buffer markers, which means they move when you edit.  It then expands 
out to just after "int a;" and just before "int c" to capture any edits 
that might include white-space, comments, etc.  It then looks into the 
tag scope of b to see what the reparse token is.  It will be empty in 
this case, so it kicks of a lex/parse starting with your %start token.

It takes however many tags it finds (0, 1, or more) and splices that 
list back into the original tag list.  Thus, if you edit in multiple 
tokens, it will splice them all in for you.

If the lex/parse step fails (ie - unterminated string or block) then it 
assumes you aren't done editing, and does nothing, and kicks of a 
reparse again later.  Sometimes it might throw up it's hands and dirty 
the whole buffer and start from scratch.

If you instead have:

struct foo {
   int a;

   int b;

   int c;
};

and do the same operation, when the lex/reparse occurs, it discovers the 
parent token is for "foo", and kicks off the parse using the nonterminal 
saved in "int b" and restricts other operations to within the bounds of 
foo.  If the edit block of 'foo' is exceeded, then all of "foo" is 
reparsed using the top %start token.


For all this to work, the structure of the language is one where 
"EXPANDFULL" is used to recurse into the parse on a section of text that 
is itself meant to create a list of tags whose 'parent' is another tag. 
  ie - you need to implement "semantic-tag-components" for your language 
and teach it about each type of tag that is a parent of other tags, and 
the parsing of those parent tags should be calling EXPANDFULL to create 
those tags.

It should not be necessary to override the various parts of the 
incremental parser. In the past I thought that might be useful, but 
AFAIK, all languages so far conform to the structure it uses, so it has 
not be necessary.

You had a different question regarding INDENT_BLOCK, which you would 
probably find useful.  In your grammar you need to define tokens for 
INDENT and DEDENT, and then you define a block token for INDENT_BLOCK 
that indicates that the block starts with INDENT and ends with DEDENT. 
This needs to work with the lexer.  For langauges using single character 
block delimiters like { and }, you can use the built-in 
semantic-lex-paren-or-list when you define the parser.  It uses the 
syntax table to find \s( as a match, and uses "forward-list" to create 
the BLOCK token.  It looks at the lexer depth flags to decide if it 
instead needs to create the { token instead.

In Python, the DEDENT token is not part of the syntax table, so you will 
see that wisent-python-lex-beginning-of-line will try to determine what 
kind of indentation it is, and convert that into either a DEDENT (see 
comment "indentation increased"), whitespace (see comment "no change in 
indentation"), or INDENT_BLOCK token (see comment "add INDENT_BLOCK 
token".  In that way, all beginning of lines are handled the same way, 
but different kind of lexical tokens are emitted.

I hope this helps.
Eric


------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140