SwiftStudies / OysterKit

OysterKit is a framework that provides a native Swift scanning, lexical analysis, and parsing capabilities. In addition it provides a language that can be used to rapidly define the rules used by OysterKit called STLR
BSD 2-Clause "Simplified" License
178 stars 23 forks source link

You must declare the name of the grammar before any other declarations (e.g. grammar <your-grammar-name>) from 47 to 47 #85

Closed eimantas closed 6 years ago

eimantas commented 6 years ago

I'm trying to build an stlr file for swift comments (taken from "The Swift Programming Language" book).

This is my grammar file: swift.stlr

grammar SwiftComments

whitespace = whitespace-item whitespace?

whitespaceItem = lineBreak | comment | multiline-comment |
                  "\u0000" | "\u0009" | "\u000B" | "\u000C" | "\u0020"

lineBreak = "\u000A" | "\u000D" | "\u000D\u000A"

comment = "//" commentText lineBreak
multilineComment = "/*" multilineCommentText "*/"

commentText = commentTextItem commentText?
commentTextItem = /[^\r\n]/

multilineCommentText = multitlineCommentTextItem multitlineCommentText?
multilineCommentTextItem = (>> !"/*" | !"*/") (multilineComment | commentTextItem)

When I run stlrc -g swift.stlr I get the error in issue title. Any pointers to where I got this wrong?

SwiftStudies commented 6 years ago

Apologies for the confusing error message, with all the refactoring some things have been lost.

Right in your STLR there are a couple of issues. At the moment STLR doesn't support the Unicode characters in "\uXXXX". If you'd be good enough to raise an enhancement request I'll try and get it in the next PR (which should be at the end of the the weekend). In the short term you can achieve it with a regular expression (e.g. /\x{0000}/). For brevity it may be worth wrapping all of the UTF-8 codes in a single regular expression

lineBreak = /\x{000A}|\x{000D}|\x{000D}\x{000A}/

Although there again... you can actually do that more easily with .newline

Please let me know how you get on

eimantas commented 6 years ago

Thanks for the explanation!

I've simplified stlr file to the following and still receive the same error:

grammar SwiftComments

whitespace = whitespace-item whitespace?

lineBreak = .newLine

whitespaceItem = lineBreak | comment | multiline-comment

comment = "//" commentText lineBreak
multilineComment = "/*" multilineCommentText "*/"

commentText = commentTextItem commentText?
commentTextItem = /[^\r\n]/

multilineCommentText = multitlineCommentTextItem multitlineCommentText?
multilineCommentTextItem = (>> !"/*" | !"*/") (multilineComment | commentTextItem)
SwiftStudies commented 6 years ago

It won't like the - in whitespace-item and you've correctly defined it as whitespaceItem a little further down.

In multilineCommentTextItem what are you trying to do? The lookahead will only apply to the first terminal. Did you mean >>!( "/*" | "*/") (Lookahead and only proceed if the next two characters aren't /* or */)?

eimantas commented 6 years ago

Did you mean >>!( "/" | "/") (Lookahead and only proceed if the next two characters aren't / or /)?

This is exactly what I was trying to achieve! 👍

Sadly, still the same error. The grammar file now is:

grammar SwiftComments

whitespace = whitespaceItem whitespace?

lineBreak = .newLine

whitespaceItem = lineBreak | comment | multilineComment

comment = "//" commentText lineBreak
multilineComment = "/*" multilineCommentText "*/"

commentText = commentTextItem commentText?
commentTextItem = /[^\r\n]/

multilineCommentText = multitlineCommentTextItem multitlineCommentText?
multilineCommentTextItem = >>!( "/*" | "*/") (multilineComment | commentTextItem)

Another question: how would i go about negative lookahead for the .newLine? Would something like this work:

commentTextItem = >>!.newLine

(i.e. process everything up to the new line)

SwiftStudies commented 6 years ago

Do please keep letting me know about problems. I'm sorry the error reporting is so bad at the moment. I was literally sitting here making notes on what I wanted for the new architecture to make this better. I might do a quick push to the 0.6 branch to make it at least dump all the error messages out not just the top one.

eimantas commented 6 years ago

I'm still getting the same error though .(

SwiftStudies commented 6 years ago

Yes I'm just trying to figure out why... Next error is it's .newline not .newLine but running it through the debugger again to see if there's anything after that.

SwiftStudies commented 6 years ago
grammar SwiftComments

whitespace = whitespaceItem whitespace?

lineBreak = .newline

whitespaceItem = lineBreak | comment | multilineComment

comment = "//" commentText lineBreak
multilineComment = "/*" multilineCommentText "*/"

commentText = commentTextItem commentText?
commentTextItem = /[^\r\n]/

multilineCommentText = multitlineCommentTextItem multitlineCommentText?
multilineCommentTextItem = >>!("/*" | "*/") (multilineComment | commentTextItem)
SwiftStudies commented 6 years ago

I'll get an improvement to error reporting pushed to development/0.6 first thing tomorrow, there's a little bit of complexity to it that I'd forgotten about, so I just want to take some careful steps... but the above works.

Note if you want to generate the rules AND the structure (you should use the 0.6 branch) you should use:

stlrc -g swift.stlr -l swiftIR -ot ~/Desktop/
eimantas commented 6 years ago

Alright, the latest grammar file seems to be working, however your offered command doesn't work:

~/Desktop % stlrc -g ./swift.stlr -l swiftIR -ot .  
Option provided is not a valid option.
For more information run:stlrc help or -h or --help
SwiftStudies commented 6 years ago

Are you on the development/0.6 branch?

Parameters if you are running from the Desktop would be

stlrc generate -g swift.stlr -ot ~/Desktop/ -l swiftIR

You can also generate just the rules with

stlrc generate -g swift.stlr -ot ~/Desktop/ -l swift

But you will have to add

import Foundation
import OysterKit

At the top of the generated file

SwiftStudies commented 6 years ago

I've just pushed to development/0.6 some changes that at least mean all the error messages that stop parsing get out to the message. The results are quite overwhelming at the moment but I wanted to at least get you something that would keep you moving forward.

SwiftStudies commented 6 years ago

Note I've also fixed my guidance on what command line parameters to use... should have been

stlrc generate -g swift.stlr -ot ~/Desktop/ -l swiftIR
SwiftStudies commented 6 years ago

I've corrected a couple more typos in the grammar

grammar SwiftComments

whitespace = whitespaceItem whitespace?

lineBreak = .newline

whitespaceItem = lineBreak | comment | multilineComment

comment = "//" commentText lineBreak
multilineComment = "/*" multilineCommentText "*/"

commentText = commentTextItem commentText?
commentTextItem = >>!.endOfFile !lineBreak 

multilineCommentText = multilineCommentTextItem multilineCommentText?
multilineCommentTextItem = >>!("/*" | "*/") (multilineComment | commentTextItem)

Now your grammar goes into an infinite loop causes a segfault... Your commentText rule looks overly complex, I think it could just resolve down to !lineBreak* lineBreak? Anyhow, I've also put a check for the end of the file in there too. It scans to the end but fails there because there's not really an "exit" condition probably because the rest of the grammar isn't there. So it will match what you type then hit the end of the file and fail.

eimantas commented 6 years ago

Epic! Checking out development/0.6, using the latest stlr file and running the command works as a charm!

Thank you very much for your help!

SwiftStudies commented 6 years ago

I'm working on improving error descriptions right now keep an eye on #87 when its closed it will be worth updating from development/0.6 again.

SwiftStudies commented 6 years ago

Just pushed some pretty significant improvements up into development/0.6. Well worth picking up.