cnhkmcp 2.3.4__py3-none-any.whl → 2.3.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. cnhkmcp/__init__.py +1 -1
  2. cnhkmcp/untracked/APP/Tranformer/validator.py +149 -32
  3. cnhkmcp/untracked/APP/blueprints/parsetab.py +60 -0
  4. cnhkmcp/untracked/APP/blueprints/validator.py +1080 -0
  5. cnhkmcp/untracked/APP/requirements.txt +0 -0
  6. cnhkmcp/untracked/APP/static/decoder.js +164 -38
  7. cnhkmcp/untracked/APP/static/simulator.js +15 -15
  8. cnhkmcp/untracked/APP/templates/feature_engineering.html +78 -78
  9. cnhkmcp/untracked/APP/templates/idea_house.html +49 -49
  10. cnhkmcp/untracked/APP/templates/index.html +58 -58
  11. cnhkmcp/untracked/APP/templates/inspiration_house.html +64 -64
  12. cnhkmcp/untracked/APP/templates/paper_analysis.html +21 -21
  13. cnhkmcp/untracked/APP/templates/simulator.html +38 -38
  14. cnhkmcp/untracked/APP/templates/transformer_web.html +24 -24
  15. cnhkmcp/untracked/APP/trailSomeAlphas/skills/brain-data-feature-engineering/SKILL.md +15 -15
  16. cnhkmcp/untracked/APP/trailSomeAlphas/skills/brain-feature-implementation/data/fundamental28_GLB_delay1/fundamental28_GLB_1_idea_1769927658009727000.json +10 -0
  17. cnhkmcp/untracked/APP/trailSomeAlphas/skills/brain-feature-implementation/data/fundamental28_GLB_delay1/fundamental28_GLB_1_idea_1769927658519220600.json +10 -0
  18. cnhkmcp/untracked/APP/trailSomeAlphas/skills/brain-feature-implementation/data/fundamental28_GLB_delay1/fundamental28_GLB_1_idea_1769927659002708800.json +10 -0
  19. cnhkmcp/untracked/APP/trailSomeAlphas/skills/brain-feature-implementation/data/fundamental28_GLB_delay1/fundamental28_GLB_1_idea_1769927659510920900.json +10 -0
  20. cnhkmcp/untracked/APP/trailSomeAlphas/skills/brain-feature-implementation/data/fundamental28_GLB_delay1/fundamental28_GLB_1_idea_1769927659982673800.json +10 -0
  21. cnhkmcp/untracked/APP/trailSomeAlphas/skills/brain-feature-implementation/scripts/validator.py +153 -32
  22. cnhkmcp/untracked/APP//321/210/342/224/220/320/240/321/210/320/261/320/234/321/206/320/231/320/243/321/205/342/225/235/320/220/321/206/320/230/320/241.py +46 -0
  23. cnhkmcp/untracked/skills/alpha-expression-verifier/scripts/validator.py +149 -32
  24. cnhkmcp/untracked/skills/{brain-inspectTemplate-create-Setting → brain-inspectRawTemplate-create-Setting}/SKILL.md +8 -2
  25. cnhkmcp/untracked/skills/brain-inspectRawTemplate-create-Setting/ace.log +0 -0
  26. cnhkmcp/untracked/skills/brain-inspectRawTemplate-create-Setting/idea_context.json +15 -0
  27. cnhkmcp/untracked/skills/brain-inspectRawTemplate-create-Setting/scripts/__init__.py +0 -0
  28. cnhkmcp/untracked/skills/{brain-inspectTemplate-create-Setting → brain-inspectRawTemplate-create-Setting}/scripts/parse_idea_file.py +33 -1
  29. cnhkmcp/untracked/skills/brain-inspectRawTemplate-create-Setting/scripts/parsetab.py +60 -0
  30. cnhkmcp/untracked/skills/brain-inspectRawTemplate-create-Setting/scripts/validator.py +1086 -0
  31. {cnhkmcp-2.3.4.dist-info → cnhkmcp-2.3.5.dist-info}/METADATA +1 -1
  32. {cnhkmcp-2.3.4.dist-info → cnhkmcp-2.3.5.dist-info}/RECORD +49 -37
  33. /cnhkmcp/untracked/{skills/brain-inspectTemplate-create-Setting → APP/hkSimulator}/ace.log +0 -0
  34. /cnhkmcp/untracked/{skills/brain-inspectTemplate-create-Setting/scripts/__init__.py → APP/hkSimulator/autosim_20260201_172428.log} +0 -0
  35. /cnhkmcp/untracked/skills/{brain-inspectTemplate-create-Setting → brain-inspectRawTemplate-create-Setting}/.gitignore +0 -0
  36. /cnhkmcp/untracked/skills/{brain-inspectTemplate-create-Setting → brain-inspectRawTemplate-create-Setting}/ace_lib.py +0 -0
  37. /cnhkmcp/untracked/skills/{brain-inspectTemplate-create-Setting → brain-inspectRawTemplate-create-Setting}/config.json +0 -0
  38. /cnhkmcp/untracked/skills/{brain-inspectTemplate-create-Setting → brain-inspectRawTemplate-create-Setting}/fundamental28_GLB_1_idea_1769874845978315000.json +0 -0
  39. /cnhkmcp/untracked/skills/{brain-inspectTemplate-create-Setting → brain-inspectRawTemplate-create-Setting}/helpful_functions.py +0 -0
  40. /cnhkmcp/untracked/skills/{brain-inspectTemplate-create-Setting → brain-inspectRawTemplate-create-Setting}/scripts/build_alpha_list.py +0 -0
  41. /cnhkmcp/untracked/skills/{brain-inspectTemplate-create-Setting → brain-inspectRawTemplate-create-Setting}/scripts/fetch_sim_options.py +0 -0
  42. /cnhkmcp/untracked/skills/{brain-inspectTemplate-create-Setting → brain-inspectRawTemplate-create-Setting}/scripts/load_credentials.py +0 -0
  43. /cnhkmcp/untracked/skills/{brain-inspectTemplate-create-Setting → brain-inspectRawTemplate-create-Setting}/scripts/process_template.py +0 -0
  44. /cnhkmcp/untracked/skills/{brain-inspectTemplate-create-Setting → brain-inspectRawTemplate-create-Setting}/scripts/resolve_settings.py +0 -0
  45. /cnhkmcp/untracked/skills/{brain-inspectTemplate-create-Setting → brain-inspectRawTemplate-create-Setting}/sim_options_snapshot.json +0 -0
  46. {cnhkmcp-2.3.4.dist-info → cnhkmcp-2.3.5.dist-info}/WHEEL +0 -0
  47. {cnhkmcp-2.3.4.dist-info → cnhkmcp-2.3.5.dist-info}/entry_points.txt +0 -0
  48. {cnhkmcp-2.3.4.dist-info → cnhkmcp-2.3.5.dist-info}/licenses/LICENSE +0 -0
  49. {cnhkmcp-2.3.4.dist-info → cnhkmcp-2.3.5.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,7 @@
1
1
  ---
2
- name: brain-inspecttemplate-create-setting
2
+ name: brain-inspectRawTemplate-create-setting
3
3
  description: >-
4
+ This skill is to inspect raw BRAIN template only, it has nothing to do with enhanced templates. do not use it for enhanced templates.
4
5
  Reads a BRAIN template/idea JSON (template/idea/expression_list) like
5
6
  fundamental28_GLB_1_idea_<timestamp>.json, fetches valid simulation setting options
6
7
  via ace_lib.get_instrument_type_region_delay, resolves region/delay/universe/neutralization,
@@ -9,7 +10,7 @@ description: >-
9
10
  user-invocable: true
10
11
  ---
11
12
 
12
- # brain-inspectTemplate-create-Setting
13
+ # brain-inspectRawTemplate-create-Setting
13
14
 
14
15
  This skill is designed for *stable, repeatable runs*.
15
16
 
@@ -25,6 +26,11 @@ AI reasoning (Critical Step):
25
26
  - **Loop**: The AI can decide on **multiple** setting combinations if the idea is ambiguous or worth testing broadly.
26
27
  - e.g., Run 1: `Universe=TOP3000`, `Neutralization=INDUSTRY`
27
28
  - e.g., Run 2: `Universe=TOPDIV3000`, `Neutralization=MARKET`
29
+ - **Context**: There are two kinds of Netralization in BRAIN:
30
+ - `Market Investment Neutralization`: Neutralizes to make a net-zero investment within a market peers, or industry peers, or subindustry peers, or exchanges peers.
31
+ - `Risk Neutralization`: Neutralizes against predefined risk factors in BRAIN, such as Barra 'SLOW' factors, Barra 'FAST' factors, 'CROWDING' factors, ect. that you can choose from the `settings_candidates.json`.
32
+ - `Decay`: This is a time linear decay apply to your Alpha signals, it can smooth out short-term fluctuations but may also reduce responsiveness to market changes.
33
+ - You should choose wisesly based on the template's idea and intent.
28
34
  - **Action**: For EACH chosen setting, call `scripts/build_alpha_list.py` passing the settings as a JSON string.
29
35
  - The script will **APPEND** to `alpha_list.json`, allowing comprehensive test coverage.
30
36
 
@@ -0,0 +1,15 @@
1
+ {
2
+ "input_file": "D:\\BRAINProject\\cnhkmcp\\cnhkmcp\\untracked\\skills\\brain-inspectRawTemplate-create-Setting\\fundamental28_GLB_1_idea_1769874845978315000.json",
3
+ "dataset_id": "fundamental28",
4
+ "region": "GLB",
5
+ "delay": 1,
6
+ "template": "divide({value_03501a}, {value_02300q})",
7
+ "idea": "**Concept**: Equity Capital Structure Ratio\n- **Sample Fields Used**: `value_03501a`, `value_02300q`\n- **Definition**: Common equity as a proportion of total assets (Equity/Assets ratio)\n- **Why This Feature**: Measures financial leverage and capital structure conservatism; higher equity indicates lower leverage risk\n- **Logical Meaning**: Ownership cushion against asset value declines; inverse of leverage ratio\n- **is filling nan necessary**: we have some operators to fill nan value like ts_backfill() or group_mean() etc. however, in some cases, if the nan value itself has some meaning, then we should not fill it blindly since it may introduce some bias. so before filling nan value, we should think about whether the nan value has some meaning in the specific scenario. Annual equity vs quarterly assets creates frequency mismatch; do not interpolate annual data to quarterly.\n- **Directionality**: Higher values indicate less leveraged, more conservative capital structure (typically lower risk)\n- **Boundary Conditions**: Values near 1 indicate no debt; near 0 indicate highly leveraged or negative equity situations",
8
+ "expression_list": [
9
+ "divide(fnd28_bdea_value_03501a, fnd28_bsassetq_value_02300q)",
10
+ "divide(fnd28_bdea_value_03501a, fnd28_nddq1_value_02300q)",
11
+ "divide(fnd28_fsa1_value_03501a, fnd28_bsassetq_value_02300q)",
12
+ "divide(fnd28_fsa1_value_03501a, fnd28_nddq1_value_02300q)"
13
+ ],
14
+ "validation_failures": []
15
+ }
@@ -12,6 +12,17 @@ SKILL_DIR = Path(__file__).resolve().parents[1]
12
12
  if str(SKILL_DIR) not in sys.path:
13
13
  sys.path.insert(0, str(SKILL_DIR))
14
14
 
15
+ # Add scripts dir to path to allow direct import of validator
16
+ SCRIPTS_DIR = SKILL_DIR / "scripts"
17
+ if str(SCRIPTS_DIR) not in sys.path:
18
+ sys.path.insert(0, str(SCRIPTS_DIR))
19
+
20
+ try:
21
+ from validator import ExpressionValidator
22
+ except ImportError:
23
+ # Fallback or try strict relative if above fails
24
+ from scripts.validator import ExpressionValidator
25
+
15
26
 
16
27
  @dataclass(frozen=True)
17
28
  class IdeaContext:
@@ -22,6 +33,7 @@ class IdeaContext:
22
33
  template: str
23
34
  idea: str
24
35
  expression_list: list[str]
36
+ validation_failures: list[dict[str, Any]] = None # Tracks invalid expressions and their errors
25
37
 
26
38
 
27
39
  _FILENAME_RE = re.compile(
@@ -56,6 +68,25 @@ def build_context(path: Path) -> IdeaContext:
56
68
  if not isinstance(expression_list, list) or not all(isinstance(x, str) for x in expression_list):
57
69
  raise ValueError("expression_list must be a list of strings")
58
70
 
71
+ # Validate expressions
72
+ validator = ExpressionValidator()
73
+ valid_expressions = []
74
+ validation_failures = []
75
+
76
+ print(f"Validating {len(expression_list)} expressions...")
77
+ for expr in expression_list:
78
+ result = validator.check_expression(expr)
79
+ if result['valid']:
80
+ valid_expressions.append(expr)
81
+ else:
82
+ print(f" Invalid expression found: {expr[:50]}... Errors: {result['errors']}")
83
+ validation_failures.append({
84
+ "expression": expr,
85
+ "errors": result['errors']
86
+ })
87
+
88
+ print(f"Validation complete. {len(valid_expressions)} valid, {len(validation_failures)} failed.")
89
+
59
90
  return IdeaContext(
60
91
  input_file=str(path),
61
92
  dataset_id=dataset,
@@ -63,7 +94,8 @@ def build_context(path: Path) -> IdeaContext:
63
94
  delay=delay,
64
95
  template=template,
65
96
  idea=idea,
66
- expression_list=expression_list,
97
+ expression_list=valid_expressions,
98
+ validation_failures=validation_failures
67
99
  )
68
100
 
69
101
 
@@ -0,0 +1,60 @@
1
+
2
+ # parsetab.py
3
+ # This file is automatically generated. Do not edit.
4
+ # pylint: disable=W,C,R
5
+ _tabversion = '3.10'
6
+
7
+ _lr_method = 'LALR'
8
+
9
+ _lr_signature = 'ASSIGN BOOLEAN CATEGORY COMMA DIVIDE EQUAL FIELD FUNCTION GREATER GREATEREQUAL IDENTIFIER LESS LESSEQUAL LPAREN MINUS NOTEQUAL NUMBER PLUS RPAREN STRING TIMESexpression : comparison\n| expression EQUAL comparison\n| expression NOTEQUAL comparison\n| expression GREATER comparison\n| expression LESS comparison\n| expression GREATEREQUAL comparison\n| expression LESSEQUAL comparisoncomparison : term\n| comparison PLUS term\n| comparison MINUS termterm : factor\n| term TIMES factor\n| term DIVIDE factorfactor : NUMBER\n| STRING\n| FIELD\n| CATEGORY\n| IDENTIFIER\n| BOOLEAN\n| MINUS factor\n| LPAREN expression RPAREN\n| function_callfunction_call : FUNCTION LPAREN args RPARENargs : arg_list\n| emptyarg_list : arg\n| arg_list COMMA argarg : expression\n| IDENTIFIER ASSIGN expressionempty :'
10
+
11
+ _lr_action_items = {'NUMBER':([0,4,12,15,16,17,18,19,20,21,22,23,24,27,46,47,],[6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,]),'STRING':([0,4,12,15,16,17,18,19,20,21,22,23,24,27,46,47,],[7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,]),'FIELD':([0,4,12,15,16,17,18,19,20,21,22,23,24,27,46,47,],[8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,]),'CATEGORY':([0,4,12,15,16,17,18,19,20,21,22,23,24,27,46,47,],[9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,]),'IDENTIFIER':([0,4,12,15,16,17,18,19,20,21,22,23,24,27,46,47,],[10,10,10,10,10,10,10,10,10,10,10,10,10,44,44,10,]),'BOOLEAN':([0,4,12,15,16,17,18,19,20,21,22,23,24,27,46,47,],[11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,]),'MINUS':([0,2,3,4,5,6,7,8,9,10,11,12,13,15,16,17,18,19,20,21,22,23,24,25,27,28,29,30,31,32,33,34,35,36,37,38,44,45,46,47,],[4,22,-8,4,-11,-14,-15,-16,-17,-18,-19,4,-22,4,4,4,4,4,4,4,4,4,4,-20,4,22,22,22,22,22,22,-9,-10,-12,-13,-21,-18,-23,4,4,]),'LPAREN':([0,4,12,14,15,16,17,18,19,20,21,22,23,24,27,46,47,],[12,12,12,27,12,12,12,12,12,12,12,12,12,12,12,12,12,]),'FUNCTION':([0,4,12,15,16,17,18,19,20,21,22,23,24,27,46,47,],[14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,]),'$end':([1,2,3,5,6,7,8,9,10,11,13,25,28,29,30,31,32,33,34,35,36,37,38,45,],[0,-1,-8,-11,-14,-15,-16,-17,-18,-19,-22,-20,-2,-3,-4,-5,-6,-7,-9,-10,-12,-13,-21,-23,]),'EQUAL':([1,2,3,5,6,7,8,9,10,11,13,25,26,28,29,30,31,32,33,34,35,36,37,38,43,44,45,49,],[15,-1,-8,-11,-14,-15,-16,-17,-18,-19,-22,-20,15,-2,-3,-4,-5,-6,-7,-9,-10,-12,-13,-21,15,-18,-23,15,]),'NOTEQUAL':([1,2,3,5,6,7,8,9,10,11,13,25,26,28,29,30,31,32,33,34,35,36,37,38,43,44,45,49,],[16,-1,-8,-11,-14,-15,-16,-17,-18,-19,-22,-20,16,-2,-3,-4,-5,-6,-7,-9,-10,-12,-13,-21,16,-18,-23,16,]),'GREATER':([1,2,3,5,6,7,8,9,10,11,13,25,26,28,29,30,31,32,33,34,35,36,37,38,43,44,45,49,],[17,-1,-8,-11,-14,-15,-16,-17,-18,-19,-22,-20,17,-2,-3,-4,-5,-6,-7,-9,-10,-12,-13,-21,17,-18,-23,17,]),'LESS':([1,2,3,5,6,7,8,9,10,11,13,25,26,28,29,30,31,32,33,34,35,36,37,38,43,44,45,49,],[18,-1,-8,-11,-14,-15,-16,-17,-18,-19,-22,-20,18,-2,-3,-4,-5,-6,-7,-9,-10,-12,-13,-21,18,-18,-23,18,]),'GREATEREQUAL':([1,2,3,5,6,7,8,9,10,11,13,25,26,28,29,30,31,32,33,34,35,36,37,38,43,44,45,49,],[19,-1,-8,-11,-14,-15,-16,-17,-18,-19,-22,-20,19,-2,-3,-4,-5,-6,-7,-9,-10,-12,-13,-21,19,-18,-23,19,]),'LESSEQUAL':([1,2,3,5,6,7,8,9,10,11,13,25,26,28,29,30,31,32,33,34,35,36,37,38,43,44,45,49,],[20,-1,-8,-11,-14,-15,-16,-17,-18,-19,-22,-20,20,-2,-3,-4,-5,-6,-7,-9,-10,-12,-13,-21,20,-18,-23,20,]),'RPAREN':([2,3,5,6,7,8,9,10,11,13,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,48,49,],[-1,-8,-11,-14,-15,-16,-17,-18,-19,-22,-20,38,-30,-2,-3,-4,-5,-6,-7,-9,-10,-12,-13,-21,45,-24,-25,-26,-28,-18,-23,-27,-29,]),'COMMA':([2,3,5,6,7,8,9,10,11,13,25,28,29,30,31,32,33,34,35,36,37,38,40,42,43,44,45,48,49,],[-1,-8,-11,-14,-15,-16,-17,-18,-19,-22,-20,-2,-3,-4,-5,-6,-7,-9,-10,-12,-13,-21,46,-26,-28,-18,-23,-27,-29,]),'PLUS':([2,3,5,6,7,8,9,10,11,13,25,28,29,30,31,32,33,34,35,36,37,38,44,45,],[21,-8,-11,-14,-15,-16,-17,-18,-19,-22,-20,21,21,21,21,21,21,-9,-10,-12,-13,-21,-18,-23,]),'TIMES':([3,5,6,7,8,9,10,11,13,25,34,35,36,37,38,44,45,],[23,-11,-14,-15,-16,-17,-18,-19,-22,-20,23,23,-12,-13,-21,-18,-23,]),'DIVIDE':([3,5,6,7,8,9,10,11,13,25,34,35,36,37,38,44,45,],[24,-11,-14,-15,-16,-17,-18,-19,-22,-20,24,24,-12,-13,-21,-18,-23,]),'ASSIGN':([44,],[47,]),}
12
+
13
+ _lr_action = {}
14
+ for _k, _v in _lr_action_items.items():
15
+ for _x,_y in zip(_v[0],_v[1]):
16
+ if not _x in _lr_action: _lr_action[_x] = {}
17
+ _lr_action[_x][_k] = _y
18
+ del _lr_action_items
19
+
20
+ _lr_goto_items = {'expression':([0,12,27,46,47,],[1,26,43,43,49,]),'comparison':([0,12,15,16,17,18,19,20,27,46,47,],[2,2,28,29,30,31,32,33,2,2,2,]),'term':([0,12,15,16,17,18,19,20,21,22,27,46,47,],[3,3,3,3,3,3,3,3,34,35,3,3,3,]),'factor':([0,4,12,15,16,17,18,19,20,21,22,23,24,27,46,47,],[5,25,5,5,5,5,5,5,5,5,5,36,37,5,5,5,]),'function_call':([0,4,12,15,16,17,18,19,20,21,22,23,24,27,46,47,],[13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,]),'args':([27,],[39,]),'arg_list':([27,],[40,]),'empty':([27,],[41,]),'arg':([27,46,],[42,48,]),}
21
+
22
+ _lr_goto = {}
23
+ for _k, _v in _lr_goto_items.items():
24
+ for _x, _y in zip(_v[0], _v[1]):
25
+ if not _x in _lr_goto: _lr_goto[_x] = {}
26
+ _lr_goto[_x][_k] = _y
27
+ del _lr_goto_items
28
+ _lr_productions = [
29
+ ("S' -> expression","S'",1,None,None,None),
30
+ ('expression -> comparison','expression',1,'p_expression','validator.py',404),
31
+ ('expression -> expression EQUAL comparison','expression',3,'p_expression','validator.py',405),
32
+ ('expression -> expression NOTEQUAL comparison','expression',3,'p_expression','validator.py',406),
33
+ ('expression -> expression GREATER comparison','expression',3,'p_expression','validator.py',407),
34
+ ('expression -> expression LESS comparison','expression',3,'p_expression','validator.py',408),
35
+ ('expression -> expression GREATEREQUAL comparison','expression',3,'p_expression','validator.py',409),
36
+ ('expression -> expression LESSEQUAL comparison','expression',3,'p_expression','validator.py',410),
37
+ ('comparison -> term','comparison',1,'p_comparison','validator.py',417),
38
+ ('comparison -> comparison PLUS term','comparison',3,'p_comparison','validator.py',418),
39
+ ('comparison -> comparison MINUS term','comparison',3,'p_comparison','validator.py',419),
40
+ ('term -> factor','term',1,'p_term','validator.py',426),
41
+ ('term -> term TIMES factor','term',3,'p_term','validator.py',427),
42
+ ('term -> term DIVIDE factor','term',3,'p_term','validator.py',428),
43
+ ('factor -> NUMBER','factor',1,'p_factor','validator.py',435),
44
+ ('factor -> STRING','factor',1,'p_factor','validator.py',436),
45
+ ('factor -> FIELD','factor',1,'p_factor','validator.py',437),
46
+ ('factor -> CATEGORY','factor',1,'p_factor','validator.py',438),
47
+ ('factor -> IDENTIFIER','factor',1,'p_factor','validator.py',439),
48
+ ('factor -> BOOLEAN','factor',1,'p_factor','validator.py',440),
49
+ ('factor -> MINUS factor','factor',2,'p_factor','validator.py',441),
50
+ ('factor -> LPAREN expression RPAREN','factor',3,'p_factor','validator.py',442),
51
+ ('factor -> function_call','factor',1,'p_factor','validator.py',443),
52
+ ('function_call -> FUNCTION LPAREN args RPAREN','function_call',4,'p_function_call','validator.py',471),
53
+ ('args -> arg_list','args',1,'p_args','validator.py',475),
54
+ ('args -> empty','args',1,'p_args','validator.py',476),
55
+ ('arg_list -> arg','arg_list',1,'p_arg_list','validator.py',483),
56
+ ('arg_list -> arg_list COMMA arg','arg_list',3,'p_arg_list','validator.py',484),
57
+ ('arg -> expression','arg',1,'p_arg','validator.py',491),
58
+ ('arg -> IDENTIFIER ASSIGN expression','arg',3,'p_arg','validator.py',492),
59
+ ('empty -> <empty>','empty',0,'p_empty','validator.py',499),
60
+ ]