- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试更新此 glsl-parser它使用旧的 pyparsing 版本和 python2.x 到 python3.x 和最新的 pyparsing 版本(2.1.9 atm)。
我不知道哪个 pyparsing 版本使用了原始源代码,但它一定很旧,因为在阅读 pyparsing news 后仍在使用 keepOriginalText
辅助方法。我看到这条评论 Removed keepOriginalText helper method,它在很久以前就被弃用了。由 originalTextFor 取代。
无论如何,这里是使用python3.5.1 & pyparsing==2.1.9移植的第一次尝试:
# -*- coding: utf-8 -*-
# -----------------------------------------------------------------------------
# Copyright (c) 2014, Nicolas P. Rougier
# Distributed under the (new) BSD License. See LICENSE.txt for more info.
# -----------------------------------------------------------------------------
import pyparsing
keywords = ("attribute const uniform varying break continue do for while"
"if else"
"in out inout"
"float int void bool true false"
"lowp mediump highp precision invariant"
"discard return"
"mat2 mat3 mat4"
"vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 sampler2D samplerCube"
"struct")
reserved = ("asm"
"class union enum typedef template this packed"
"goto switch default"
"inline noinline volatile public static extern external"
"interface flat long short double half fixed unsigned superp"
"input output"
"hvec2 hvec3 hvec4 dvec2 dvec3 dvec4 fvec2 fvec3 fvec4 sampler1D sampler3D"
"sampler1DShadow sampler2DShadow"
"sampler2DRect sampler3DRect sampler2DRectShadow"
"sizeof cast"
"namespace using")
precision = "lowp mediump high"
storage = "const uniform attribute varying"
# Tokens
# ----------------------------------
LPAREN = pyparsing.Literal("(").suppress()
RPAREN = pyparsing.Literal(")").suppress()
LBRACK = pyparsing.Literal("[").suppress()
RBRACK = pyparsing.Literal("]").suppress()
LBRACE = pyparsing.Literal("{").suppress()
RBRACE = pyparsing.Literal("}").suppress()
IDENTIFIER = pyparsing.Word(pyparsing.alphas + '_', pyparsing.alphanums + '_')
TYPE = pyparsing.Word(pyparsing.alphas + '_', pyparsing.alphanums + "_")
END = pyparsing.Literal(";").suppress()
INT = pyparsing.Word(pyparsing.nums)
FLOAT = pyparsing.Regex(
'[+-]?(((\d+\.\d*)|(\d*\.\d+))([eE][-+]?\d+)?)|(\d*[eE][+-]?\d+)')
STORAGE = pyparsing.Regex('|'.join(storage.split(' ')))
PRECISION = pyparsing.Regex('|'.join(precision.split(' ')))
STRUCT = pyparsing.Literal("struct").suppress()
# ------------------------
def get_prototypes(code):
"""
Get all function declarations
Code example
------------
mediump vec3 function_1(vec4);
vec3 function_2(float a, float b);
"""
PARAMETER = pyparsing.Group(pyparsing.Optional(PRECISION).setResultsName("precision") +
TYPE.setResultsName("type") +
pyparsing.Optional(IDENTIFIER).setResultsName("name"))
PARAMETERS = pyparsing.delimitedList(PARAMETER).setResultsName(
"arg", listAllMatches=True)
PROTOTYPE = (pyparsing.Optional(PRECISION).setResultsName("precision") +
TYPE.setResultsName("type") +
IDENTIFIER.setResultsName("name") +
LPAREN + pyparsing.Optional(PARAMETERS).setResultsName("args") + RPAREN +
END)
PROTOTYPE.ignore(pyparsing.cStyleComment)
for (token, start, end) in PROTOTYPE.scanString(code):
print(token.precision, token.type, token.name, '(',)
for arg in token.args:
print(arg.precision, arg.type, arg.name, ',',)
print(')')
# ------------------------
def get_functions(code):
"""
Get all function definitions
Code example
------------
mediump vec3 compute_normal(vec4);
"""
PARAMETER = pyparsing.Group(pyparsing.Optional(PRECISION).setResultsName("precision") +
TYPE.setResultsName("type") +
pyparsing.Optional(IDENTIFIER).setResultsName("name"))
PARAMETERS = pyparsing.delimitedList(PARAMETER).setResultsName(
"arg", listAllMatches=True)
FUNCTION = (pyparsing.Optional(PRECISION).setResultsName("precision") +
TYPE.setResultsName("type") +
IDENTIFIER.setResultsName("name") +
LPAREN + pyparsing.Optional(PARAMETERS).setResultsName("args") + RPAREN +
pyparsing.nestedExpr("{", "}").setParseAction(pyparsing.originalTextFor).setResultsName("code"))
FUNCTION.ignore(pyparsing.cStyleComment)
for (token, start, end) in FUNCTION.scanString(code):
print(token.precision, token.type, token.name, '(',)
for arg in token.args:
print(arg.precision, arg.type, arg.name, ',',)
print(') { ... }')
# print token.code
# print code[start:end]
# ------------------------
def get_version(code):
"""
Get shader version (if specified)
Code example
------------
#version 120
"""
VERSION = (
pyparsing.Literal("#") + pyparsing.Keyword("version")).suppress() + INT
for (token, start, end) in VERSION.scanString(code):
version = token[0]
# print code[start:end]
return version
# ------------------------
def get_declarations(code):
"""
Get all declarations prefixed with a storage qualifier.
Code example
------------
uniform lowp vec4 fg_color = vec4(1),
bg_color = vec4(vec3(0),1);
"""
# Callable expression
EXPRESSION = pyparsing.Forward()
ARG = pyparsing.Group(EXPRESSION) | IDENTIFIER | FLOAT | INT
ARGS = pyparsing.delimitedList(ARG)
EXPRESSION << IDENTIFIER + \
pyparsing.Group(LPAREN + pyparsing.Optional(ARGS) + RPAREN)
# Value
VALUE = (EXPRESSION | pyparsing.Word(pyparsing.alphanums + "_()+-/*")
).setParseAction(pyparsing.originalTextFor)
# Single declaration
VARIABLE = (IDENTIFIER.setResultsName("name") +
pyparsing.Optional(LBRACK +
(INT | IDENTIFIER).setResultsName("size")
+ RBRACK) +
pyparsing.Optional(pyparsing.Literal("=").suppress() + VALUE.setResultsName("value")))
# Several declarations at once
DECLARATION = (STORAGE.setResultsName("storage") +
pyparsing.Optional(PRECISION).setResultsName("precision") +
TYPE.setResultsName("type") +
pyparsing.delimitedList(VARIABLE.setResultsName("variable", listAllMatches=True)) +
END)
DECLARATION.ignore(pyparsing.cStyleComment)
for (tokens, start, end) in DECLARATION.scanString(code):
for token in tokens.variable:
print(tokens.storage, tokens.precision, tokens.type,)
print(token.name, token.size)
# ------------------------
def get_definitions(code):
"""
Get all structure definitions and associated declarations.
Code example
------------
uniform struct Light {
vec4 position;
vec3 color;
} light0, light1;
"""
# Single declaration
DECLARATION = pyparsing.Group(IDENTIFIER.setResultsName("name") +
pyparsing.Optional(LBRACK +
(INT | IDENTIFIER).setResultsName("size") +
RBRACK))
# Several declarations at once
DECLARATIONS = (pyparsing.Optional(PRECISION) +
TYPE +
pyparsing.delimitedList(DECLARATION) +
END)
# Definition + declarations
DEFINITION = (STRUCT +
IDENTIFIER.setResultsName("name") +
LBRACE + pyparsing.OneOrMore(DECLARATIONS).setResultsName('content') + RBRACE +
pyparsing.Optional(pyparsing.delimitedList(DECLARATION.setResultsName("declarations", listAllMatches=True))) +
END)
DEFINITION.ignore(pyparsing.cStyleComment)
for (tokens, start, end) in DEFINITION.scanString(code):
for token in tokens.declarations:
print(tokens.name, token.name)
# print tokens.content
# ----------------
def resolve(code):
"""
Expand const and preprocessor definitions in order to get constant values.
Return the transformed code
"""
constants = {}
DEFINITION = (pyparsing.Literal("#") + pyparsing.Literal("define") +
IDENTIFIER.setResultsName("name") +
pyparsing.restOfLine.setResultsName("value"))
VALUE = pyparsing.Word(pyparsing.alphanums + "_()+-/*")
DECLARATION = (pyparsing.Literal("const") +
TYPE.setResultsName("type") +
IDENTIFIER.setResultsName("name") +
pyparsing.Literal("=") +
VALUE.setResultsName("value") +
pyparsing.Literal(";"))
REFERENCE = pyparsing.Forward()
def process_definition(s, l, t):
value = REFERENCE.transformString(t.value)
constants[t.name] = value
REFERENCE << pyparsing.MatchFirst(
map(pyparsing.Keyword, constants.keys()))
return "#define " + t.name + " " + value
def process_declaration(s, l, t):
value = REFERENCE.transformString(t.value)
constants[t.name] = value
REFERENCE << pyparsing.MatchFirst(
map(pyparsing.Keyword, constants.keys()))
return "const " + t.type + " " + t.name + "=" + value + ";"
def process_reference(s, l, t):
return constants[t[0]]
REFERENCE.setParseAction(process_reference)
DEFINITION.setParseAction(process_definition)
DECLARATION.setParseAction(process_declaration)
EXPANDER = REFERENCE | DEFINITION | DECLARATION
code = EXPANDER.transformString(code)
for key, val in constants.items():
constants[key] = eval(val)
return code, constants
# -----------------------------------------------------------------------------
if __name__ == '__main__':
code = """
#version 120
#define A (1)
const int B=(A+2);
#define C (B+3)
const int D=C+4;
uniform float array[D];
struct Point {
vec4 position;
float size;
};
uniform struct Light {
vec4 position;
vec3 color;
} light0, light1;
const float PI = 3.14159265358979323846264;
const float SQRT_2 = 1.4142135623730951;
uniform vec4 fg_color = vec4(1),
bg_color = vec4(vec3(0),1);
mediump vec3 compute_normal(vec4 position, vec3 orientation);
vec3 /* */ compute_light(vec4, vec3, float intensity)
{
vec3 hello;
vec3 hello;
}
"""
code, _ = resolve(code)
print("GLSL version: %s\n" % get_version(code))
get_definitions(code)
get_declarations(code)
get_prototypes(code)
get_functions(code)
# code = """
# #if A
# #if B
# #if C
# #endif
# #endif
# #endif
# """
# IF = (pyparsing.Literal('#') + (pyparsing.Keyword('if') | pyparsing.Keyword('ifdef') | pyparsing.Keyword('ifndef')))
# ENDIF = (pyparsing.Literal('#') + pyparsing.Keyword('endif'))
# MACRO = (IF + pyparsing.restOfLine() +
# SkipTo(ENDIF, include=True)).setParseAction(pyparsing.originalTextFor)
# for (tokens, start, end) in MACRO.scanString(code):
# print tokens
当您尝试运行上面的 mcve 代码时,您将得到:
GLSL version: 120
('Light', 'light0')
('Light', 'light1')
d:\virtual_envs\py2711\lib\site-packages\pyparsing.py:3536: SyntaxWarning: Cannot combine element of type <type 'int'> with ParserElement
matchExpr = locMarker("_original_start") + expr + endlocMarker("_original_end")
d:\virtual_envs\py2711\lib\site-packages\pyparsing.py:3536: SyntaxWarning: Cannot combine element of type <type 'NoneType'> with ParserElement
matchExpr = locMarker("_original_start") + expr + endlocMarker("_original_end")
Traceback (most recent call last):
File "D:\sources\personal\python\pyqt\pyshaders\gui\glsl-parser.py", line 311, in <module>
get_declarations(code)
File "D:\sources\personal\python\pyqt\pyshaders\gui\glsl-parser.py", line 173, in get_declarations
for (tokens, start, end) in DECLARATION.scanString(code):
File "d:\virtual_envs\py2711\lib\site-packages\pyparsing.py", line 1258, in scanString
nextLoc,tokens = parseFn( instring, preloc, callPreParse=False )
File "d:\virtual_envs\py2711\lib\site-packages\pyparsing.py", line 1084, in _parseNoCache
loc,tokens = self.parseImpl( instring, preloc, doActions )
File "d:\virtual_envs\py2711\lib\site-packages\pyparsing.py", line 2576, in parseImpl
loc, exprtokens = e._parse( instring, loc, doActions )
File "d:\virtual_envs\py2711\lib\site-packages\pyparsing.py", line 1084, in _parseNoCache
loc,tokens = self.parseImpl( instring, preloc, doActions )
File "d:\virtual_envs\py2711\lib\site-packages\pyparsing.py", line 2576, in parseImpl
loc, exprtokens = e._parse( instring, loc, doActions )
File "d:\virtual_envs\py2711\lib\site-packages\pyparsing.py", line 1084, in _parseNoCache
loc,tokens = self.parseImpl( instring, preloc, doActions )
File "d:\virtual_envs\py2711\lib\site-packages\pyparsing.py", line 3038, in parseImpl
loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False )
File "d:\virtual_envs\py2711\lib\site-packages\pyparsing.py", line 1084, in _parseNoCache
loc,tokens = self.parseImpl( instring, preloc, doActions )
File "d:\virtual_envs\py2711\lib\site-packages\pyparsing.py", line 2576, in parseImpl
loc, exprtokens = e._parse( instring, loc, doActions )
File "d:\virtual_envs\py2711\lib\site-packages\pyparsing.py", line 1110, in _parseNoCache
tokens = fn( instring, tokensStart, retTokens )
File "d:\virtual_envs\py2711\lib\site-packages\pyparsing.py", line 831, in wrapper
ret = func(*args[limit[0]:])
File "d:\virtual_envs\py2711\lib\site-packages\pyparsing.py", line 3542, in originalTextFor
matchExpr.setParseAction(extractText)
AttributeError: 'NoneType' object has no attribute 'setParseAction'
我还在学习pyparsing,这里有什么问题?
最佳答案
originalTextFor
不是解析 Action ,而是将解析 Action 附加到已定义表达式的辅助方法。在您的示例中,它用在两个地方:
# Value
VALUE = (EXPRESSION | pyparsing.Word(pyparsing.alphanums + "_()+-/*")
).setParseAction(pyparsing.originalTextFor)
FUNCTION = (pyparsing.Optional(PRECISION).setResultsName("precision") +
TYPE.setResultsName("type") +
IDENTIFIER.setResultsName("name") +
LPAREN + pyparsing.Optional(PARAMETERS).setResultsName("args") + RPAREN +
pyparsing.nestedExpr("{", "}").setParseAction(pyparsing.originalTextFor).setResultsName("code"))
将这些更改为:
# Value
VALUE = pyparsing.originalTextFor(EXPRESSION |
pyparsing.Word(pyparsing.alphanums + "_()+-/*"))
FUNCTION = (pyparsing.Optional(PRECISION).setResultsName("precision") +
TYPE.setResultsName("type") +
IDENTIFIER.setResultsName("name") +
LPAREN + pyparsing.Optional(PARAMETERS).setResultsName("args") + RPAREN +
pyparsing.originalTextFor(pyparsing.nestedExpr("{", "}")).setResultsName("code"))
您可能会发现 setResultsName
的最新 pyparsing 形式看起来更简洁一些,但旧形式仍然可以正常工作:
FUNCTION = (pyparsing.Optional(PRECISION)("precision") +
TYPE("type") +
IDENTIFIER("name") +
LPAREN + pyparsing.Optional(PARAMETERS)("args") + RPAREN +
pyparsing.originalTextFor(pyparsing.nestedExpr("{", "}"))("code"))
如果您进行此更改,那些使用 listAllMatches
的地方将通过向名称参数添加“*”来处理:
pyparsing.delimitedList(VARIABLE("variable*"))
关于python - glsl 解析器使用 pyparsing 给出 AttributeErrors,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39702882/
我试图理解这两个概念。我正在阅读的手册对它们非常简短,像多 channel 算法这样的东西对我来说是新的。我想要一些示例(不是代码),说明我需要在哪里使用不变变量或精确变量,只是为了获得一个大致的想法
您好,我正在尝试获得一个快速的圆角矩形 glsl 着色器,但我只设法使用此函数( https://github.com/marklundin/glsl-sdf-primitives/blob/mast
这可能是一个简单的问题。作为 GLSL 的新手,我宁愿在这里问。 现在,在顶点着色器中,我可以通过以下方式获取世界坐标系中的位置: gl_Position = ftransform();
我想知道是否有人拥有完整、有效且高效的代码来在 glsl 中进行双三次纹理过滤。有这个: http://www.codeproject.com/Articles/236394/Bi-Cubic-and
真的有两个问题... GLSL ES 2 是完全独立的语言,还是 GLSL 的特殊版本? 在“标准库”函数、语法和功能方面,它们之间有什么区别? 我正在为一个针对 Windows、Mac 和 iPad
从GLSL文档(https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/length.xhtml)中,长度函数“计算 vector 的长度”
我想在 GLSL 着色器中实现颜色矩阵滤镜,但找不到与此相关的任何文档。我是着色器世界的新手(我自己从未编写过代码)所以如果我的解释/词汇没有意义,请原谅我。 到目前为止我可以收集到的信息: 一个颜色
我刚刚开始使用 openframeworks 中的着色器,并且正在尝试编写一个片段着色器,它根据片段的观看角度来更改片段的颜色。例如,给定一个矩形,如果从正面看(相机与法线平行)它会是红色,但如果从侧
似乎某些在 case 中具有输出的函数可能使用 if 语句作为底层实现,从而导致分支。我不认为它,但我想知道。 对于 sign(x),如果数字是正数、负数或零,则分别重新运行 1、-1 和 0。 那么
如何在 glsl 中执行位操作? 使用常规 C 风格的按位运算符 | , & , ^ , 或 !不起作用。 最佳答案 它们是在 GLSL 1.30 (OGL 3.0) 中引入的。 根据您想要做什么,您
最近我一直在玩 webGl,我偶然发现了一个很酷的小演示 here (来源 here )我想稍微改变一下以获得一些很酷的结果。 我对改变地形的生成方式很感兴趣。而不是分层 10 个 Octave
这是每个设备的事情吗?还是基于浏览器?抱歉问了这样一个基本问题,但我似乎找不到直接的答案。 最佳答案 它基于 OpenGL ES 2.0,并根据 the spec , 它必须支持 GLSL ES 版本
你如何在 GLSL 着色器中通过引用传递? 最佳答案 您可以将属性标记为 inout在函数签名中,这将使属性有效地“通过引用传递” 例如, void doSomething( vec3 trans,
我有一个浮点 RGBA 缓冲区,我想将其作为统一 Texel 缓冲区传递到我的计算着色器(用于只读访问,没有采样)。谁能告诉我如何在 GLSL 中执行此操作? 我能找到的所有示例似乎都在跳过该主题,或
我有一些参数从 CPU 传递到 GPU,这些参数对于所有片段都是恒定的,但在每一帧上都会发生变化(我使用的是 GLSL ES 1.1)。对于这些值,我应该使用制服还是属性?属性可能因顶点而异,所以我的
我已经看到这个伪随机数生成器在着色器中使用,引用here and there around the web : float rand(vec2 co){ return fract(sin(dot(
我尝试在结构内初始化数组,如下所示: struct myStruct { vec3 data[20] = vec3[20] (vec3(1, 1, 1), vec3( 1, -1, 1), v
我尝试在结构内初始化数组,如下所示: struct myStruct { vec3 data[20] = vec3[20] (vec3(1, 1, 1), vec3( 1, -1, 1), v
在 GLSL 着色器中,出于各种原因,我经常需要几个函数来修改单个值(例如,片段着色器使用四个函数来应用照明、纹理、镜面反射和雾化)。我可以想到至少三种方法来传递这些值进行修改: 使用 inout每个
我在 SL 引用中搜索了“copy”,但找不到任何相关内容。 如果我有: float a[3] = float[3] (1.0,2.0,3.0); float b[3] = a; 是 b现在指向 a
我是一名优秀的程序员,十分优秀!