I'm trying to build an LL(*) grammar to parse VBScript, starting from the VBScript language definition included with the editor, and I'm following the documentation and examples trying to figure them out.
I'm having a really hard time though, I believe I wrote enough of the grammar to get some results but my biggest issue is what to do with the root production.
I noticed that the SimpleLanguage parser example only ever declares Functions and nothing else and so the root production
this.Root.Production = functionDeclaration.OnError(AdvanceToDefaultState).ZeroOrMore();
fails on any piece of code that doesn't contain only functions.
I've been trying unsuccessfully to figure exactly what to do to parse anything other than a single item, I tried to use | operators to specify multiple non-terminals in the hope of being able to parse them as well but the tree never goes very far.
What should I do in this case to be able to parse and generate an AST tree something like the following VBScript?
Private Const PAR_PH = " pH"
Public Parametri
Public verbose
Sub ShowMessage(msgText)
MsgBox msgText
Message = msgText
End Sub
Function Calcola()
Dim dblValue, strValue
'Other code here
Calcola = True
End Function
Is there an example grammar that could help me understand better what to do?
I would have expected to be able to look at a VB.NET grammar definition but I can't find anything of the sort around.
This is the production that I made until now, as it stands right now it fails on the very first line, I edited most of this from the SimpleLanguage example and even added some new terminals to the language definition.
functionDeclaration.CanMatchCallback = CanAlwaysMatch;
functionAccessExpression.CanMatchCallback = CanMatchFunctionAccessExpression;
accessModifierOpt.CanMatchCallback = CanAlwaysMatch;
this.Root.Production = functionDeclaration.OnError(AdvanceToDefaultState).ZeroOrMore();
nl.Production = @lineTerminator + nl.Optional();
constantDeclaration.Production = @accessModifier + @keyword["Const"] + @identifier + @operator["="] + expression + nl;
subDecl.Production = @keyword["Sub"] + @identifier + @openParenthesis +
functionParameterList.Optional() + @closeParenthesis + block +
@endSub + nl
accessModifierOpt.Production = @accessModifier.Optional();
functionDeclaration.Production = accessModifier.Optional() + @keyword["Function"] + @identifier + @openParenthesis +
functionParameterList.Optional() + @closeParenthesis + block + @endFunction + nl;
functionParameterList.Production = @identifier + (@punctuation + @identifier).ZeroOrMore();
statement.Production = block | emptyStatement | @operator;
block.Production = @nl + (statement.ZeroOrMore()) + @nl;
emptyStatement.Production = @documentEnd.ToTerm().ToProduction();
primaryExpression.Production = numberExpression
| functionAccessExpression
| simpleName
| parenthesizedExpression;
functionAccessExpression.Production = @identifier + @openParenthesis + functionArgumentList.Optional() +
@closeParenthesis;
numberExpression.Production = @integerNumber.ToTerm().ToProduction();
simpleName.Production = @identifier.ToTerm().ToProduction();
parenthesizedExpression.Production = @openParenthesis + expression + @closeParenthesis;
functionArgumentList.Production = expression + (@punctuation["."] + expression).ZeroOrMore();
multiplicativeExpression.Production = primaryExpression +
((@multiplication | @division) + multiplicativeExpression)
.Optional();
additiveExpression.Production = multiplicativeExpression +
((@addition | @subtraction) + additiveExpression).Optional();
equalityExpression.Production = additiveExpression +
((@operator["="] | @inequality) + equalityExpression).Optional();
expression.Production = equalityExpression.ToTerm().ToProduction();
assignmentStatement.Production = @keyword["Set"] + @identifier + @operator["="] + expression + nl;
variableDeclarationStatement.Production = @dim + @identifier + (@punctuation[","] + @identifier).ZeroOrMore() + nl;
statement.Production = block
| variableDeclarationStatement
| emptyStatement
| assignmentStatement
| constantDeclaration;