Semantic design advice

SyntaxEditor for Windows Forms Forum

Posted 9 years ago by David
Avatar
Hi, I have a question about a certain design feature of my semantic parsing. Here's an example...

I have non-terminals, StatementList, Statement, CaseStatement and SwitchStatement.

A StatementList holds Statements and a CaseStatement can appear inside the body of a SwitchStatement. CaseStatement and SwitchStatement both inherit Statement, so can be stored in the StatementList.

But it is syntactically wrong for a CaseStatement to appear anywhere except inside a SwitchStatement body.

So is it better to not have StatementList parse statements of type CaseStatement or to have it parse them, and have my syntax error module post an error?

On the otherhand if I do not allow the StatementList non-terminal to read CaseStatement; I know I can use the failure code tag to throw up an error stating that it shouldn't be there, but how can I get the TextRange of it?

Hope you understood my question, thank you.

[Modified at 01/09/2011 08:46 PM]

Comments (7)

Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi David,

When we did C#/VB (which is similar), we implemented a SwitchSection instead of a CaseStatement. SwitchSection doesn't inherit Statement since as you said it can't be used in normal statement locations.

You cna use text ranges of tokens to report errors like:
this.ReportSyntaxError(this.LookAheadToken.TextRange, message);


Actipro Software Support

Posted 9 years ago by David
Avatar
Thanks for your reply.

Ok, so I have no excluded CaseStatement from the Statement non-terminal and so it can only appear in the body of a SwitchStatement(SwitchBody).

My problem is that it won't report a syntax error when it finds a CaseStatement in the StatementList. Here is the non-terminal...

<NonTerminal Key="StatementList" Parameters="out StatementList statementList">
<Production>
<![CDATA[
    <%
        int startOffset = this.LookAheadToken.StartOffset;
        statementList = new StatementList();
        
        Statement statement = null;
    %>
        {
            "Statement<@ out statement @>
            <+
                statementList.Statements.Add(statement);
                statementList.TextRange = new TextRange(startOffset, this.Token.EndOffset);
            +>
            <-
                this.ReportSyntaxError(this.LookAheadToken.TextRange, "Statement Expected");        
            ->"
        }
    
]]>
</Production>
</NonTerminal>
I expect this code to attempt to look for a Statement. As CaseStatement is not included in the Statement non-terminal, then it should fail, and it should underline the token 'Case'. Maybe I am doing something fundamentally wrong?
Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi David,

In that case Statement's first set doesn't match on 'Case' so it will just exit your {...} loop. What you can do instead is stick an alternation within this loop that looks for the 'Case' terminal. If found then report an error on the Token (not LookAheadToken).


Actipro Software Support

Posted 9 years ago by David
Avatar
Thanks, I realise that will work, but I guess I'm looking for a more general case, when anything could be there, not just a CaseStatement.

I want to be able to report that it shouldn't be there, whilst still processing to look for any other statements, like VS does.

I can't list everything as alternations. What if something appears that's not defined in my grammar or as a valid token, eg '$' or '£'? How do I continue on from this?

Thanks for your time.
Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi David,

You could do something like this in Statement where the alternation option is at the end and catches everything, then moves to the next valid token that can start a Statement:

| <? true ?> ( error reporting code here )


Actipro Software Support

Posted 9 years ago by David
Avatar
That's great, I always forgot about conditionals :) So now I can use 'AdvanceToNext()' and 'continue;' to keep the loop going, and attempting to parse statements.

I'm so close, there's just another problem :)

The StatementList non-terminal uses an iteration block to find any amount of Statements. The parser generates C# code that looks at the next token, and compares it in the MultiMatchSets. So the loop will run as long as the next token can start a Statement, else it just terminates.

How can I keep the loop going even if the next token(s) can't create a Statement? This sounds illogical I know :)

Thanks again.
Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi David,

To do that you'd have to break out your loop into user code probably, like this:
<%
while (!this.IsAtEnd) {
    if (IsNonTerminal("Statement")) {
%>
    "Statement"
<%
    }
    else {
        // Report error and advance to next valid statement start
    }
}
%>


Actipro Software Support

The latest build of this product (v2018.1 build 0342) was released 11 days ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.