# Copyright 2021-2024 Cambridge Quantum Computing Ltd.## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License."""Web parser==========A parser that retrieves parses from a web server, thus forgoes the needto have a parser installed locally."""from__future__importannotations__all__=['WebParser','WebParseError']importsysfromtqdm.autoimporttqdmfromlambeq.core.globalsimportVerbosityLevelfromlambeq.core.utilsimport(SentenceBatchType,tokenised_batch_type_check,untokenised_batch_type_check)fromlambeq.text2diagram.ccg_parserimportCCGParserfromlambeq.text2diagram.ccg_treeimportCCGTreeSERVICE_URLS={'depccg':'https://cqc.pythonanywhere.com/tree/json'}
def__str__(self)->str:return(f'Web parser could not parse {repr(self.sentence)}')
[docs]classWebParser(CCGParser):"""Wrapper that allows passing parser queries to an online service."""
[docs]def__init__(self,parser:str='depccg',verbose:str=VerbosityLevel.SUPPRESS.value)->None:"""Initialise a web parser. Parameters ---------- parser : str, optional The web parser to use. By default, this is depccg parser. verbose : str, default: 'suppress', See :py:class:`VerbosityLevel` for options. """ifparser.lower()notinSERVICE_URLS:raiseValueError(f'Unknown web parser: {parser}')self.service_url=SERVICE_URLS[parser]ifnotVerbosityLevel.has_value(verbose):raiseValueError(f'`{verbose}` is not a valid verbose value for ''WebParser.')self.verbose=verbose
[docs]defsentences2trees(self,sentences:SentenceBatchType,tokenised:bool=False,suppress_exceptions:bool=False,verbose:str|None=None)->list[CCGTree|None]:"""Parse multiple sentences into a list of :py:class:`.CCGTree` s. Parameters ---------- sentences : list of str, or list of list of str The sentences to be parsed. suppress_exceptions : bool, default: False Whether to suppress exceptions. If :py:obj:`True`, then if a sentence fails to parse, instead of raising an exception, its return entry is :py:obj:`None`. verbose : str, optional See :py:class:`VerbosityLevel` for options. If set, it takes priority over the :py:attr:`verbose` attribute of the parser. Returns ------- list of :py:class:`CCGTree` or None The parsed trees. May contain :py:obj:`None` if exceptions are suppressed. Raises ------ URLError If the service URL is not well formed. ValueError If a sentence is blank or type of the sentence does not match `tokenised` flag. WebParseError If the parser fails to obtain a parse tree from the server. """importrequestsifverboseisNone:verbose=self.verboseifnotVerbosityLevel.has_value(verbose):raiseValueError(f'`{verbose}` is not a valid verbose value for ''WebParser.')iftokenised:ifnottokenised_batch_type_check(sentences):raiseValueError('`tokenised` set to `True`, but variable ''`sentences` does not have type ''`list[list[str]]`.')sentences=[' '.join(sentence)forsentenceinsentences]else:ifnotuntokenised_batch_type_check(sentences):raiseValueError('`tokenised` set to `False`, but variable ''`sentences` does not have type ''`list[str]`.')sent_list:list[str]=[str(s)forsinsentences]sentences=[' '.join(sentence.split())forsentenceinsent_list]empty_indices=[]fori,sentenceinenumerate(sentences):ifnotsentence:ifsuppress_exceptions:empty_indices.append(i)else:raiseValueError(f'Sentence at index {i} is blank.')foriinreversed(empty_indices):delsentences[i]trees:list[CCGTree|None]=[]ifverbose==VerbosityLevel.TEXT.value:print('Parsing sentences.',file=sys.stderr)forsentenceintqdm(sentences,desc='Parsing sentences',leave=False,disable=verbose!=VerbosityLevel.PROGRESS.value):params={'sentence':sentence}try:data=requests.get(self.service_url,params=params).json()exceptrequests.RequestExceptionase:ifsuppress_exceptions:tree=Noneelifisinstance(e,requests.JSONDecodeError):raiseWebParseError(str(sentence))fromeelse:raiseeelse:tree=CCGTree.from_json(data)trees.append(tree)foriinempty_indices:trees.insert(i,None)returntrees