On 3 Jun 2011, at 00:26, Ben Schmidt wrote:

>> I'm experiencing a problem where a valid piece of syntax (a variable
>> declaration) sudden;y changes state (becomes an (invalid) procedure
>> call) following the insertion elsewhere in the file of an indexed
>> assignment.
> [...]
>> Here is a simple test file that shows the problem, which shows that
>> the problem exhibits itself even when the assignment that provokes the
>> error is inside a comment.
> 
> This indeed seems very strange. With sync fromstart, I can't imagine why
> this would happen, particularly in the case where it's in a comment, as
> it's a completely irrelevant syntax item.
> 
> Maybe it's a bug in Vim's syntax engine. We seem to have been finding a
> few of those recently.
> 
>> 1. sclProcedureCall is declared earlier in the syntax file than
>> sclStringDeclaration.
> 
> Does that matter? Did you try swapping them? If it doesn't matter,
> probably not worth mentioning!
> 
>> 2. I use 'foldmethod=syntax' and use folding aggressively to detect
>> bad syntax.
> 
> I don't think this is relevant either. With foldmethod=manual the
> problem still occurs.
> 
>> 3. sclStringDeclaration is a region with 'start=/\ze\<string\>/
>> skip=/\(\<string\|)\},\)\_s*/ end=/,/ end=/$/'
> 
> Seems a bit different to that in the actual syntax file. The one in the
> syntax file seems a bit more sensible, though.
> 
>> 4. The reason for the \ze in the 'start' pattern is to make the folds
>> work for declarations and assignments.
> 
> OK. That is helpful to know.
> 
>> 5. An indexed assignment is modelled as a procedure call - it has the
>> same semantics as a procedure call returning a reference has.
> 
> OK.
> 
>> Can anyone suggest what might be causing this problem?
> 
> Not yet. Your minimal test data was wonderful, though I've managed to
> minimise it even more. This is enough to show the problem:
> 
> string ( 80 ) message := ""
> @ )=
> 
> In fact, the problem is easier to see there, because Vim seems to update
> more quickly as you edit. Modifying the comment causes the highlighting
> to change 'in realtime'.
> 
> I'm still a bit baffled.
> 
> Perhaps work on this even smaller example and see if you can minimise
> the syntax file. This example doesn't require a procedure body or
> anything like that, so should be able to work with a really small syntax
> file, and that should help us pinpoint either the problem with the
> syntax file or the bug in Vim.

Here's the smallest sample syntax file that I've so far managed to exhibit both 
behaviours (correct and incorrect), minus the highlight groups.

========================================================================
syntax  case    ignore

syntax  sync    fromstart

syntax  match   sclError        /\S\+/
syntax  match   sclError        /\k\+/

syntax match    sclIdentifier contained /\%(\<string\>\)\@!\<\a\k*\>/

syntax  match   sclNumber       /\<\d\+\>/      contained

syntax  match   sclStringEsc1 contained
        \       /""/
syntax  match   sclStringEsc2 contained
        \       /''/

syntax  match   sclStringConst
        \       /""/

syntax  match   sclParens       contained /[([{})\]]/

syntax  match   sclComma        contained /,/

syntax  match   sclAssignOp     contained /:\==/
"
"       Now start building syntactic constructs from them
"
syntax  region  sclParen        fold keepend extend 
contains=@sclExpr,@sclAlwaysValid
        \       matchgroup=sclParens
        \       start=/[[({]/ end=/[])}]/

syntax  region  sclProcedureCall        keepend extend 
contains=sclIdentifier,sclActualParameters,@sclAlwaysValid
        \       start=/\<\a\k*\>\ze\s*[[({]/
        \       end=/[])}]\zs/

syntax  match   sclType         /\<string\>/

syntax  region  sclStringAssignment     fold keepend extend 
        \       contains=sclProcedureCall,sclAssignOp,@sclStringExpr,
        \               @sclAlwaysValid
        \       start=/\<\a\k*\>\s*[[({]\_.\{-}[])}]\s*:\==\_s*/
        \       skip=/\(:\==\|+\|-\|\<and\>\|\<or\>\|\<after\|\<before\>\)\_s*/
        \       end=/\ze,/ end=/\ze;/ end=/$/
syntax  region  sclStringAssignment     fold keepend extend 
contains=sclIdentifier,
        \               sclAssignOp,@sclStringExpr,@sclAlwaysValid
        \       start=/\<\a\k*\>\s*\<is\>\_s*/
        \       
skip=/\(\<is\>\|+\|-\|\<and\>\|\<or\>\|\<after\|\<before\>\)\_s*/
        \       end=/\ze,/ end=/\ze;/ end=/$/
syntax  region  sclStringAssignment     fold keepend extend 
contains=sclIdentifier,
        \               sclAssignOp,@sclStringExpr,@sclAlwaysValid
        \       start=/\<\a\k*\>\s*:\==\_s*/
        \       skip=/\(:\==\|+\|-\|\<and\>\|\<or\>\|\<after\|\<before\>\)\_s*/
        \       end=/\ze,/ end=/\ze;/ end=/$/

syntax  region  sclStringAdvisoryLength keepend extend contains=@sclIntExpr,
        \               @sclAlwaysValid
        \       matchgroup=sclParens
        \       start=/(/
        \       matchgroup=sclParens
        \       end=/)\_s*/

syntax  region  sclActualParameters     fold keepend 
contains=sclComment,@sclExpr
        \       matchgroup=sclParens
        \       start=/[[({]/
        \       matchgroup=sclParens
        \       end=/[])}]/

syntax  region  sclStringDeclaration    fold keepend extend contains=sclType,
        \               
sclStringAdvisoryLength,sclStringAssignment,sclIdentifier,
        \               sclComma,@sclAlwaysValid
        \       start=/\<string\>\_s*\%((\_.\{-})\_s*\)\=/
        \       skip=/\(\<string\>\|)\|,\)\_s*/
        \       matchgroup=sclSemiColon
        \       end=/;/ end=/$/

syntax  region  sclComment
        \       extend
        \       start=/@/ end=/\n/ end=/@/ 
syntax  region  sclComment contained
        \       extend
        \       start=/@/ end=/\n/ end=/@/ 
"
"       These clusters group useful types together
"
syntax  cluster sclIntOperand   contains=sclLocalName,sclIdentifier,sclNumber,
        \               sclProcedureCall,sclArithOp,sclParen

syntax  cluster sclStringOperand        contains=sclIdentifier,sclStringConst,
        \               sclProcedureCall,sclStringOp,sclParen

syntax  cluster sclIntExpr      contains=@sclIntOperand,sclRelOp,sclArithOp

syntax  cluster sclStringExpr   contains=@sclStringOperand,sclRelOp,sclStringOp

syntax  cluster sclExpr contains=@sclStringExpr,@sclSStringExpr,@sclIntExpr,
        \               @sclBoolExpr,sclAlwaysValid

syntax  cluster sclAlwaysValid  contains=sclComment,sclError
========================================================================

If I delete the 'syntax region sclStringAssignment' that contains the 
sclProcedureCall, then it stops misbehaving. This is, in fact, probably a more 
realistic definition, too, as I was probably trying to overload the clause by 
one straw too many - while you can assign a reference a value, you can't do it 
as part of a string declaration; I can probably live wigh leaving that as an 
sclAnonymousAssignment. 

So, while I believe that I have found a bug in the syntax engine, I now have 
something that looks, from a distance, like a work-around. Despite that, I'm 
prepared to assist in someone else's debugging of this, if I can.

Regards, Andy

-- 
Andrew Long
andrew dot long at mac dot com





Attachment: PGP.sig
Description: This is a digitally signed message part

Reply via email to