python左右解析器


pyleri的Python项目详细描述

python左右解析器

pyleri是为siridb创建的一个易于使用的解析器。我们首先使用了lrparsinglrparsing,并在我们的web控制台中编写了jslerijsleri,用于自动完成和建议。后来,我们在lrparsing模块中发现了一些小问题,并且在所有项目中都很难保持语言相同。当我们决定创建Pyleri时,可以将创建的语法导出到JavaScript、C、Python、Go和Java.<



相关项目

  • jsleri:javascript解析器
  • libcleri:c解析器
  • goleri:go parser
  • = HRFF="HTTPS://GITHUBCOM/TyrPopeTeReTeaTys/JLeRI"Re="NoFoLoLo>"JLeRi :Java解析器

安装

最简单的方法是使用pypi:

sudo pip3 install pyleri

快速使用

# Imports, note that we skip the imports in other examples...frompyleriimport(Grammar,Keyword,Regex,Sequence)# Create a Grammar Class to define your languageclassMyGrammar(Grammar):r_name=Regex('(?:"(?:[^"]*)")+')k_hi=Keyword('hi')START=Sequence(k_hi,r_name)# Compile your grammar by creating an instance of the Grammar Class.my_grammar=MyGrammar()# Use the compiled grammar to parse 'strings'print(my_grammar.parse('hi "Iris"').is_valid)# => Trueprint(my_grammar.parse('bye "Iris"').is_valid)# => Falseprint(my_grammar.parse('bye "Iris"').as_str())# => error at position 0, expecting: hi

语法

当你写语法的时候,你应该把语法分类。语法要求至少有一个start属性,这样解析器就知道从哪里开始解析。语法有一些默认属性,可以覆盖,如re_keywords,稍后将对其进行解释。语法也有一个解析方法:parse(),还有一些导出方法:export嫒js()export嫒c()export嫒py()export懔u java()如下所述。

解析

语法:

Grammar().parse(string)

parse()方法返回一个result对象,该对象具有以下属性,这些属性将在result中进一步解释:

导出j

语法:

Grammar().export_js(js_module_name='jsleri',js_template=Grammar.JS_TEMPLATE,js_indent=' '*4)

可选关键字参数:

例如,当使用快速用法语法时,这是运行my_grammar.export_js()时的输出:

/* jshint newcap: false *//* * This grammar is generated using the Grammar.export_js() method and * should be used with the jsleri JavaScript module. * * Source class: MyGrammar * Created at: 2015-11-04 10:06:06 */'use strict';(function(Regex,Sequence,Keyword,Grammar){varr_name=Regex('^(?:"(?:[^"]*)")+');vark_hi=Keyword('hi');varSTART=Sequence(k_hi,r_name);window.MyGrammar=Grammar(START,'^\w+');})(window.jsleri.Regex,window.jsleri.Sequence,window.jsleri.Keyword,window.jsleri.Grammar);

出口C

语法:

Grammar().export_c(target=Grammar.C_TARGET,c_indent=' '*4)

可选关键字参数:

返回值是包含源(C)文件和头(H)文件的元组。

例如,当使用快速用法语法时,这是运行my_grammar.export_c()时的输出:

/* * grammar.c * * This grammar is generated using the Grammar.export_c() method and * should be used with the libcleri module. * * Source class: MyGrammar * Created at: 2016-05-09 12:16:49 */#include"grammar.h"#include<stdio.h>#define CLERI_CASE_SENSITIVE 0#define CLERI_CASE_INSENSITIVE 1#define CLERI_FIRST_MATCH 0#define CLERI_MOST_GREEDY 1cleri_grammar_t*compile_grammar(void){cleri_t*r_name=cleri_regex(CLERI_GID_R_NAME,"^(?:\"(?:[^\"]*)\")+");cleri_t*k_hi=cleri_keyword(CLERI_GID_K_HI,"hi",CLERI_CASE_INSENSITIVE);cleri_t*START=cleri_sequence(CLERI_GID_START,2,k_hi,r_name);cleri_grammar_t*grammar=cleri_grammar(START,"^\\w+");returngrammar;}

还有头文件…

/* * grammar.h * * This grammar is generated using the Grammar.export_c() method and * should be used with the libcleri module. * * Source class: MyGrammar * Created at: 2016-05-09 12:16:49 */#ifndef CLERI_EXPORT_GRAMMAR_H_#define CLERI_EXPORT_GRAMMAR_H_#include<grammar.h>#include<cleri/cleri.h>cleri_grammar_t*compile_grammar(void);enumcleri_grammar_ids{CLERI_NONE,// used for objects with no nameCLERI_GID_K_HI,CLERI_GID_R_NAME,CLERI_GID_START,CLERI_END// can be used to get the enum length};#endif /* CLERI_EXPORT_GRAMMAR_H_ */

导出'u go

语法:

Grammar().export_go(go_template=Grammar.GO_TEMPLATE,go_indent='\t',go_package='grammar')

可选关键字参数:

例如,当使用快速用法语法时,这是运行my_grammar.export_go()时的输出:

sudo pip3 install pyleri
0

导出Java

语法:

sudo pip3 install pyleri
1

可选关键字参数:

  • java_template:用于导出的模板字符串。您可能需要查看grammar.java_模板中的默认字符串。
  • >代码> javaj-DutoNo./C> >:Java文件中使用的缩进。(默认值:四个空格) >代码JavaAuths:Java包的名称或在没有指定包时是不存在的。(默认值:无)
  • 是公共的:当为true时,类和构造函数被定义为公共的,否则它们将被定义为包私有的。

例如,当使用快速用法语法时,这是运行my_grammar.export_java()时的输出:

sudo pip3 install pyleri
2

导出py

语法:

sudo pip3 install pyleri
3

可选关键字参数:

  • py_module_name:pyleri模块的名称。(默认值:"pyleri")
  • py_template:用于导出的模板字符串。您可能需要查看grammar.py_模板中的默认字符串。
  • py_indent:python文件中使用的缩进。(默认值:4个空格)

例如,当使用快速用法语法时,这是运行my_grammar.export_py()时的输出:

sudo pip3 install pyleri
4

结果

parse()方法的结果包含4个属性,下面将解释这些属性。还提供了一个函数as_str(translate=none),它将 将结果显示为字符串。translate参数应该是接受元素作为参数的函数。此函数可用于 返回某些元素的自定义字符串。如果translate的返回值为none则函数将失败,尝试生成字符串值。如果 返回值为空字符串,将忽略该值。

翻译函数示例:

sudo pip3 install pyleri
5

有效吗

是有效的返回一个布尔值,真的根据给定的语法,给定的字符串有效时,假的无效时。

让我们以快速使用为例。

sudo pip3 install pyleri
6

位置

pos返回解析器必须停止的位置。(当有效时真时该值将等于应用str.rstrip()的给定字符串的长度)

让我们以快速使用为例。

sudo pip3 install pyleri
7

包含解析树。即使有效也会返回解析树,但仅在解析成功时才包含结果。树是根节点,它可以包含几个子节点节点。下面的示例将进一步阐明该结构,该示例解释了可视化解析树的方法。

示例:

sudo pip3 install pyleri
8

部分输出如下所示。

sudo pip3 install pyleri
9

一个节点包含5个属性,下面将解释这些属性:

  • 开始属性返回节点对象的开始。
  • end属性返回节点对象的结尾。
  • 元素返回元素的类型(例如repeat、sequence、keyword等)。可以将元素分配给变量;例如,在上面的示例中,keyword('hi')被分配给了khi。使用element.name将返回指定的名称k_hi。请注意,并不是给定元素是命名的;在我们的示例中,序列没有赋值,因此在这种情况下,元素没有属性名称
  • 字符串返回已分析的字符串。
  • 子节点可以返回包含更深层节点的节点对象,前提是存在任何节点。在我们的示例中,根节点有一个元素类型repeat(),从0开始,到24结束,它有两个子节点。这些子节点对象都具有元素类型序列,分别从0和12开始,依此类推。

期望

需要返回一个python set(),其中包含pyleri在pos处需要的元素。即使是有效的也是真的,这个集合中也可能有元素,例如,当可以向字符串中添加optional()元素时。如果要实现自动完成、语法错误处理、自动语法更正等功能,expecting非常有用。下面的示例将演示一种实现方法。

示例:

# Imports, note that we skip the imports in other examples...frompyleriimport(Grammar,Keyword,Regex,Sequence)# Create a Grammar Class to define your languageclassMyGrammar(Grammar):r_name=Regex('(?:"(?:[^"]*)")+')k_hi=Keyword('hi')START=Sequence(k_hi,r_name)# Compile your grammar by creating an instance of the Grammar Class.my_grammar=MyGrammar()# Use the compiled grammar to parse 'strings'print(my_grammar.parse('hi "Iris"').is_valid)# => Trueprint(my_grammar.parse('bye "Iris"').is_valid)# => Falseprint(my_grammar.parse('bye "Iris"').as_str())# => error at position 0, expecting: hi
0

输出:

# Imports, note that we skip the imports in other examples...frompyleriimport(Grammar,Keyword,Regex,Sequence)# Create a Grammar Class to define your languageclassMyGrammar(Grammar):r_name=Regex('(?:"(?:[^"]*)")+')k_hi=Keyword('hi')START=Sequence(k_hi,r_name)# Compile your grammar by creating an instance of the Grammar Class.my_grammar=MyGrammar()# Use the compiled grammar to parse 'strings'print(my_grammar.parse('hi "Iris"').is_valid)# => Trueprint(my_grammar.parse('bye "Iris"').is_valid)# => Falseprint(my_grammar.parse('bye "Iris"').as_str())# => error at position 0, expecting: hi
1

在上面的例子中,我们根据语法类分析了一个无效字符串。我们为本例构建的auto-correction()方法结合了parse()中的所有属性来创建有效的字符串。输出显示auto-correction()方法的每个递归,并连续打印期望的元素集。它随机抽取一个并将其添加到字符串中。当字符串与语法对应时,属性有效将返回。值得注意的是,预期的属性仍然包含元素,即使是有效的返回了真的。本例中的原因是因为repeat元素。

元素

pyleri有几个元素,它们都是元素的子类,可以用来创建语法。

关键字

语法:

# Imports, note that we skip the imports in other examples...frompyleriimport(Grammar,Keyword,Regex,Sequence)# Create a Grammar Class to define your languageclassMyGrammar(Grammar):r_name=Regex('(?:"(?:[^"]*)")+')k_hi=Keyword('hi')START=Sequence(k_hi,r_name)# Compile your grammar by creating an instance of the Grammar Class.my_grammar=MyGrammar()# Use the compiled grammar to parse 'strings'print(my_grammar.parse('hi "Iris"').is_valid)# => Trueprint(my_grammar.parse('bye "Iris"').is_valid)# => Falseprint(my_grammar.parse('bye "Iris"').as_str())# => error at position 0, expecting: hi
2

解析器需要匹配只是一个字符串的关键字。当匹配关键字时,我们需要告诉解析器关键字中允许哪些字符。默认情况下,pyleri使用的^\w+在python和javascript中都等于^[a-za-z0-9++。我们可以通过在语法中设置re_keywords来覆盖默认值。keyword()接受一个keyword参数ign_case来告诉解析器是否应该匹配不区分大小写。

示例:

# Imports, note that we skip the imports in other examples...frompyleriimport(Grammar,Keyword,Regex,Sequence)# Create a Grammar Class to define your languageclassMyGrammar(Grammar):r_name=Regex('(?:"(?:[^"]*)")+')k_hi=Keyword('hi')START=Sequence(k_hi,r_name)# Compile your grammar by creating an instance of the Grammar Class.my_grammar=MyGrammar()# Use the compiled grammar to parse 'strings'print(my_grammar.parse('hi "Iris"').is_valid)# => Trueprint(my_grammar.parse('bye "Iris"').is_valid)# => Falseprint(my_grammar.parse('bye "Iris"').as_str())# => error at position 0, expecting: hi
3

正则表达式

语法:

# Imports, note that we skip the imports in other examples...frompyleriimport(Grammar,Keyword,Regex,Sequence)# Create a Grammar Class to define your languageclassMyGrammar(Grammar):r_name=Regex('(?:"(?:[^"]*)")+')k_hi=Keyword('hi')START=Sequence(k_hi,r_name)# Compile your grammar by creating an instance of the Grammar Class.my_grammar=MyGrammar()# Use the compiled grammar to parse 'strings'print(my_grammar.parse('hi "Iris"').is_valid)# => Trueprint(my_grammar.parse('bye "Iris"').is_valid)# => Falseprint(my_grammar.parse('bye "Iris"').as_str())# => error at position 0, expecting: hi
4

解析器使用re模块编译正则表达式。当前版本的pyleri只支持re.ignorecase标志。 有关如何使用regex的示例,请参见快速使用示例。

代币

语法:

# Imports, note that we skip the imports in other examples...frompyleriimport(Grammar,Keyword,Regex,Sequence)# Create a Grammar Class to define your languageclassMyGrammar(Grammar):r_name=Regex('(?:"(?:[^"]*)")+')k_hi=Keyword('hi')START=Sequence(k_hi,r_name)# Compile your grammar by creating an instance of the Grammar Class.my_grammar=MyGrammar()# Use the compiled grammar to parse 'strings'print(my_grammar.parse('hi "Iris"').is_valid)# => Trueprint(my_grammar.parse('bye "Iris"').is_valid)# => Falseprint(my_grammar.parse('bye "Iris"').as_str())# => error at position 0, expecting: hi
5

代币可以是一个或多个字符,通常用于匹配+-//等运算符。当我们在pyleri需要元素的地方解析字符串对象时,它将自动转换为token()对象。

示例:

# Imports, note that we skip the imports in other examples...frompyleriimport(Grammar,Keyword,Regex,Sequence)# Create a Grammar Class to define your languageclassMyGrammar(Grammar):r_name=Regex('(?:"(?:[^"]*)")+')k_hi=Keyword('hi')START=Sequence(k_hi,r_name)# Compile your grammar by creating an instance of the Grammar Class.my_grammar=MyGrammar()# Use the compiled grammar to parse 'strings'print(my_grammar.parse('hi "Iris"').is_valid)# => Trueprint(my_grammar.parse('bye "Iris"').is_valid)# => Falseprint(my_grammar.parse('bye "Iris"').as_str())# => error at position 0, expecting: hi
6

代币

语法:

# Imports, note that we skip the imports in other examples...frompyleriimport(Grammar,Keyword,Regex,Sequence)# Create a Grammar Class to define your languageclassMyGrammar(Grammar):r_name=Regex('(?:"(?:[^"]*)")+')k_hi=Keyword('hi')START=Sequence(k_hi,r_name)# Compile your grammar by creating an instance of the Grammar Class.my_grammar=MyGrammar()# Use the compiled grammar to parse 'strings'print(my_grammar.parse('hi "Iris"').is_valid)# => Trueprint(my_grammar.parse('bye "Iris"').is_valid)# => Falseprint(my_grammar.parse('bye "Iris"').as_str())# => error at position 0, expecting: hi
7

可用于同时注册多个令牌。tokens参数应该是一个由空格分隔的标记字符串。如果给定的标记大小不同,解析器将首先尝试匹配最长的标记。

示例:

# Imports, note that we skip the imports in other examples...frompyleriimport(Grammar,Keyword,Regex,Sequence)# Create a Grammar Class to define your languageclassMyGrammar(Grammar):r_name=Regex('(?:"(?:[^"]*)")+')k_hi=Keyword('hi')START=Sequence(k_hi,r_name)# Compile your grammar by creating an instance of the Grammar Class.my_grammar=MyGrammar()# Use the compiled grammar to parse 'strings'print(my_grammar.parse('hi "Iris"').is_valid)# => Trueprint(my_grammar.parse('bye "Iris"').is_valid)# => Falseprint(my_grammar.parse('bye "Iris"').as_str())# => error at position 0, expecting: hi
8

顺序

语法:

# Imports, note that we skip the imports in other examples...frompyleriimport(Grammar,Keyword,Regex,Sequence)# Create a Grammar Class to define your languageclassMyGrammar(Grammar):r_name=Regex('(?:"(?:[^"]*)")+')k_hi=Keyword('hi')START=Sequence(k_hi,r_name)# Compile your grammar by creating an instance of the Grammar Class.my_grammar=MyGrammar()# Use the compiled grammar to parse 'strings'print(my_grammar.parse('hi "Iris"').is_valid)# => Trueprint(my_grammar.parse('bye "Iris"').is_valid)# => Falseprint(my_grammar.parse('bye "Iris"').as_str())# => error at position 0, expecting: hi
9

解析器需要匹配序列中的每个元素。

示例:

Grammar().parse(string)
0

选择

语法:

Grammar().parse(string)
1

解析器需要在给定的元素中进行选择。choice接受一个关键字参数最贪婪的默认为。当most_greedy设置为false时,解析器将在第一次匹配时停止。当true时,解析器将尝试每个元素并返回最长的匹配。将most_greedy设置为false可以提供一些额外的性能。请注意,解析器将尝试以完全相同的顺序匹配每个元素,这些元素将按照选择的顺序进行解析。

示例:让我们使用选项修改快速使用示例,以允许字符串'bye"iris'

Grammar().parse(string)
2

重复

语法:

Grammar().parse(string)
3

解析器至少需要mi元素,最多需要ma元素。当ma设置为none时,我们允许无限数量的元素。mi可以是任何等于或大于0但不大于ma的整数值

示例:

Grammar().parse(string)
4

不允许将名称绑定到同一个元素两次,而repeat(element,1,1)是将元素绑定到第二个(或更多)时间的常见解决方案。

例如,请考虑以下内容:

Grammar().parse(string)
5

列表

语法:

Grammar().parse(string)
6

list类似于repeat,但带有分隔符。逗号用作默认分隔符,但允许使用任何元素。当字符串用作分隔符时,它将转换为标记元素。mima的工作方式与repeat完全相同。可选的关键字参数opt可以设置为true以允许列表以分隔符结尾。默认设置为false这意味着列表必须以元素结尾。

示例:

Grammar().parse(string)
7

可选

语法:

Grammar().parse(string)
8

解析器寻找一个可选元素。这就像使用repeat(element,0,1)但是我们鼓励使用可选的,因为它更具可读性。(稍微快一点)

示例:

Grammar().parse(string)
9

REF

语法:

Grammar().export_js(js_module_name='jsleri',js_template=Grammar.JS_TEMPLATE,js_indent=' '*4)
0

语法可以使前向引用成为可能,从而使递归成为可能。在下面的示例中,我们创建了一个forward引用以开始,但请注意 可以引用任何元素。

< Buff行情>

警告:引用不受在中测试同一位置的保护 一个字符串。这可能会导致无限循环。 例如:

Grammar().export_js(js_module_name='jsleri',js_template=Grammar.JS_TEMPLATE,js_indent=' '*4)
1

如果需要这种递归构造,请使用prio。

示例:

Grammar().export_js(js_module_name='jsleri',js_template=Grammar.JS_TEMPLATE,js_indent=' '*4)
2

优先级

语法:

Grammar().export_js(js_module_name='jsleri',js_template=Grammar.JS_TEMPLATE,js_indent=' '*4)
3

从prio元素中选择第一个匹配项,并允许this用于递归操作。使用这个我们指向prio元素。可能下面的示例解释了如何使用priothis

< Buff行情>

注意:如有可能,请使用aref。 当字符串中的同一位置可能是 检查了不止一次。

示例:

Grammar().export_js(js_module_name='jsleri',js_template=Grammar.JS_TEMPLATE,js_indent=' '*4)
4

推荐PyPI第三方库


热门话题
afbtastypietechnicolorespresso现存tngsdkreferenceportletbigtiffemceecodingquorumcockroachdbpytestsbeerpayhumanstxtxml2rfcskillslogger数字化visualbinomialwhilie比索unrrrubber预支guestbookrheoscsuzhangxctranslinkpermalink畸变python101alphavantagehelpersnsealarmaitteamvaultwetransferapiv2invdutlettoolanelibtbxequivalentredirecpublicdnsgiturlparseawsiot