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;