blob: 01171139eca51ffbde10f70cf463e3373b1fc21f [file] [log] [blame]
Sapan Bhatia64c72512017-06-23 02:32:45 -07001__author__ = "Sapan Bhatia"
2
3__copyright__ = "Copyright (C) 2017 Open Networking Lab"
4__version__ = "1.0"
5
6import ply.lex as lex
7import ply.yacc as yacc
8
9from helpers import LexHelper, LU
10
11class FOLLexer(object):
Sapan Bhatiabdf8b382017-07-14 11:09:05 -040012 keywords = ('forall', 'exists', 'True', 'False', 'not')
Sapan Bhatia64c72512017-06-23 02:32:45 -070013
14 tokens = ['ESCAPE', 'COLON', 'IMPLIES', 'OR', 'AND', 'LPAREN', 'RPAREN', 'EQUALS', 'SYMBOL', 'LT', 'RT'] + [k.upper() for k in keywords]
15 # literals = '()+-*/=?:,.^|&~!=[]{};<>@%'
16
17 t_ignore_LINE_COMMENT = '//.*'
18 t_COLON = '\\:'
19 t_IMPLIES = '\\-\\>'
20 t_OR = '\\|'
21 t_LT = '\\<'
22 t_RT = '\\>'
23 t_AND = '\\&'
24 t_LPAREN = '\\('
25 t_RPAREN = '\\)'
26
27 t_EQUALS = '\\='
28
29 literals = '()+-*/=?:,.^|&~!=[]{};<>@%'
30
31 t_ignore = ' \t\f'
32
33 def t_newline(self, t):
34 r'\n+'
35 t.lexer.lineno += len(t.value)
36
37 def t_newline2(self, t):
38 r'(\r\n)+'
39 t.lexer.lineno += len(t.value) / 2
40
41 t_ESCAPE = r'{{ (.|\n)*? }}'
42
43 def t_BLOCK_COMMENT(self, t):
44 r'/\*(.|\n)*?\*/'
45 t.lexer.lineno += t.value.count('\n')
46
47 def t_SYMBOL(self, t):
48 '[A-Za-z_$][\.A-Za-z0-9_+$]*'
49 if t.value in FOLLexer.keywords:
50 t.type = t.value.upper()
51 return t
52
53 def t_error(self, t):
54 print("Illegal character '{}' ({}) in line {}".format(t.value[0], hex(ord(t.value[0])), t.lexer.lineno))
55 t.lexer.skip(1)
56
57
58
59class FOLParser(object):
60 tokens = FOLLexer.tokens
61 offset = 0
62 lh = LexHelper()
63
64 def setOffset(self, of):
65 self.offset = of
66 self.lh.offset = of
67
Sapan Bhatia64c72512017-06-23 02:32:45 -070068 def p_term_constant(self, p):
69 '''term : FALSE
70 | TRUE'''
71 p[0] = p[1]
72
73 def p_fole_not(self, p):
74 '''fole : NOT fole'''
75 p[0] = {p[1]: p[2]}
76
77 def p_fole_term(self, p):
78 '''fole : term'''
79 p[0] = p[1]
80
81 def p_term_symbol(self, p):
82 '''term : SYMBOL'''
83 p[0] = p[1]
84
85 def p_term_python(self, p):
Sapan Bhatiab934f722017-07-15 08:42:19 -040086 '''term : ESCAPE'''
Sapan Bhatia05beb082017-07-16 02:23:31 -040087 p[0] = {'python': p[1].lstrip('{').rstrip('}')}
Sapan Bhatia64c72512017-06-23 02:32:45 -070088
89 def p_fole_group(self, p):
90 "fole : LPAREN fole RPAREN"
91 p[0] = p[2]
92
93 def p_fole_equals(self, p):
94 "fole : term EQUALS term"
95 p[0] = {'=': (p[1], p[3])}
96
97 def p_fole_binary(self, p):
98 '''fole : fole AND fole
99 | fole OR fole
100 | fole IMPLIES fole'''
101 p[0] = {p[2]: [p[1], p[3]]}
102
103 def p_fole_quant(self, p):
104 '''fole : FORALL SYMBOL COLON fole
105 | EXISTS SYMBOL COLON fole'''
106 p[0] = {p[1]: [p[2], p[4]]}
107
108
109 def p_goal(self, p):
110 '''goal : LT fole RT'''
111 p[0] = p[2]
112
113 def p_error(self, p):
114 print('error: {}'.format(p))
115