replace peg parser with iterative approach

This commit is contained in:
2023-10-19 22:06:08 +02:00
committed by AcerecA
parent a924ca5710
commit 9e63218572
5 changed files with 232 additions and 37 deletions
+66 -22
View File
@@ -1,19 +1,33 @@
from logging import INFO, basicConfig, getLogger
from pathlib import Path
from time import time
from lsprotocol.types import (
TEXT_DOCUMENT_DIAGNOSTIC,
TEXT_DOCUMENT_DID_CHANGE,
TEXT_DOCUMENT_DID_OPEN,
TEXT_DOCUMENT_DID_SAVE,
TEXT_DOCUMENT_DOCUMENT_SYMBOL,
TEXT_DOCUMENT_PUBLISH_DIAGNOSTICS,
CompletionItem,
Diagnostic,
DiagnosticSeverity,
DidChangeTextDocumentParams,
DidOpenTextDocumentParams,
DidSaveTextDocumentParams,
DocumentDiagnosticParams,
DocumentDiagnosticReport,
DocumentSymbol,
DocumentSymbolParams,
Position,
Range,
RelatedFullDocumentDiagnosticReport,
)
from pygls.server import LanguageServer
from parsimonious import Grammar, IncompleteParseError
from skillls.parsing.iterative import IterativeParser
from .cache import Cache
from .parsing.tokenize import Locator, SkillVisitor
@@ -31,7 +45,7 @@ def parse(content: str):
path = Path(__file__).parent / "grammar.peg"
grammar = Grammar(path.read_text())
locator = Locator(content)
locator = Locator(content.split())
tree = grammar.parse(content)
iv = SkillVisitor(locator)
@@ -40,27 +54,57 @@ def parse(content: str):
return output
@server.feature(TEXT_DOCUMENT_DOCUMENT_SYMBOL)
def document_symbols(params: DocumentSymbolParams) -> list[DocumentSymbol]:
logger.warning("requested document symbols for %s", params.text_document.uri)
# @server.feature(TEXT_DOCUMENT_DOCUMENT_SYMBOL)
# def document_symbols(params: DocumentSymbolParams) -> list[DocumentSymbol]:
# logger.warning("requested document symbols for %s", params.text_document.uri)
# doc = server.workspace.get_text_document(params.text_document.uri)
# try:
# logger.warning(parse(doc.source))
# except IncompleteParseError as e:
# server.publish_diagnostics(
# params.text_document.uri,
# [
# Diagnostic(
# Range(
# Position(e.line() - 1, e.column() - 1),
# Position(len(doc.lines), 0),
# ),
# str(e),
# severity=DiagnosticSeverity.Error,
# )
# ],
# )
# return []
# @server.feature(TEXT_DOCUMENT_DIAGNOSTIC)
# def document_diagnostic(params: DocumentDiagnosticParams) -> DocumentDiagnosticReport:
# doc = server.workspace.get_text_document(params.text_document.uri)
# p = IterativeParser()
# # parsed = (e for e in parse(doc.source) if isinstance(e, DocumentSymbol))
# # diags = [
# # Diagnostic(e.range, e.name, severity=DiagnosticSeverity.Error) for e in parsed
# # ]
# diags = p(doc.lines)
# return RelatedFullDocumentDiagnosticReport(diags)
@server.feature(TEXT_DOCUMENT_DID_OPEN)
def on_open(params: DidOpenTextDocumentParams) -> None:
doc = server.workspace.get_text_document(params.text_document.uri)
try:
logger.warning(parse(doc.source))
except IncompleteParseError as e:
server.publish_diagnostics(
params.text_document.uri,
[
Diagnostic(
Range(
Position(e.line() - 1, e.column() - 1),
Position(len(doc.lines), 0),
),
str(e),
severity=DiagnosticSeverity.Error,
)
],
)
return []
p = IterativeParser()
diags = p(doc.lines)
server.publish_diagnostics(params.text_document.uri, diags, version=int(time()))
@server.feature(TEXT_DOCUMENT_DID_SAVE)
def on_save(params: DidSaveTextDocumentParams) -> None:
server.workspace.remove_text_document(params.text_document.uri)
doc = server.workspace.get_text_document(params.text_document.uri)
p = IterativeParser()
diags = p(doc.lines)
logger.warning(doc.source)
server.publish_diagnostics(params.text_document.uri, diags, version=int(time()))
def main():
@@ -69,4 +113,4 @@ def main():
if __name__ == "__main__":
file = Path(__file__).parent.parent / "examples" / "example.il"
parse(file.read_text())
out = parse(file.read_text())