transform first couple of grammar files
This commit is contained in:
parent
2e988380e4
commit
619780a913
92
lib/parser/basic.citrus
Normal file
92
lib/parser/basic.citrus
Normal file
@ -0,0 +1,92 @@
|
||||
|
||||
grammar BasicTypes
|
||||
|
||||
# space really is just space. ruby is newline sensitive, so there is more whitespace footwork
|
||||
# rule of thumb is that anything eats space behind it, but only space, no newlines
|
||||
rule space [ \t]* end
|
||||
|
||||
rule linebreak "\n" end
|
||||
|
||||
rule comment
|
||||
"#" (/.*/ !linebreak) linebreak
|
||||
end
|
||||
|
||||
rule dot '.' end
|
||||
|
||||
## Lexical syntax
|
||||
|
||||
rule number
|
||||
float | integer
|
||||
end
|
||||
|
||||
rule float
|
||||
(digits '.' digits space*) { to_str.to_f }
|
||||
end
|
||||
|
||||
rule integer
|
||||
(digits space*) { to_str.to_i }
|
||||
end
|
||||
|
||||
rule digits
|
||||
[0-9]+ ('_' [0-9]+)* # Numbers may contain underscores.
|
||||
end
|
||||
|
||||
rule lparen '(' space* end
|
||||
rule rparen ')' space* end
|
||||
|
||||
|
||||
# Hierarchical syntax
|
||||
|
||||
rule term
|
||||
additive | factor
|
||||
end
|
||||
|
||||
rule additive
|
||||
(factor operator:('+' | '-') space* term) {
|
||||
capture(:factor).value.send(capture(:operator).to_s, capture(:term).value)
|
||||
}
|
||||
end
|
||||
|
||||
rule factor
|
||||
multiplicative | prefix
|
||||
end
|
||||
|
||||
rule multiplicative
|
||||
(prefix operator:('*' | '/' | '%') space* factor) {
|
||||
capture(:prefix).value.send(capture(:operator).to_s, capture(:factor).value)
|
||||
}
|
||||
end
|
||||
|
||||
rule prefix
|
||||
prefixed | exponent
|
||||
end
|
||||
|
||||
rule prefixed
|
||||
(operator:('-' | '+' | '~') space* prefix) {
|
||||
s = capture(:operator).to_s
|
||||
s += '@' unless s == '~' # Unary + and - require an @.
|
||||
capture(:prefix).value.send(s)
|
||||
}
|
||||
end
|
||||
|
||||
rule exponent
|
||||
exponential | primary
|
||||
end
|
||||
|
||||
rule exponential
|
||||
(primary operator:'**' space* prefix) {
|
||||
capture(:primary).value.send(capture(:operator).to_s, capture(:prefix).value)
|
||||
}
|
||||
end
|
||||
|
||||
rule primary
|
||||
group | number
|
||||
end
|
||||
|
||||
rule group
|
||||
(lparen term rparen) {
|
||||
capture(:term).value
|
||||
}
|
||||
end
|
||||
|
||||
end
|
31
lib/parser/keywords.citrus
Normal file
31
lib/parser/keywords.citrus
Normal file
@ -0,0 +1,31 @@
|
||||
grammar Keywords
|
||||
include BasicTypes
|
||||
|
||||
rule keyword_begin 'begin' space? end
|
||||
rule keyword_class 'class' space? end
|
||||
rule keyword_def 'def' space? end
|
||||
rule keyword_do 'do' space? end
|
||||
rule keyword_else 'else' space? end
|
||||
rule keyword_end 'end' space? end
|
||||
rule keyword_false 'false' space? end
|
||||
rule keyword_if 'if' space? end
|
||||
rule keyword_rescue 'rescue' space? end
|
||||
rule keyword_return 'return' space? end
|
||||
rule keyword_module 'module' space? end
|
||||
rule keyword_nil 'nil' space? end
|
||||
rule keyword_unless 'unless' space? end
|
||||
rule keyword_until 'until' space? end
|
||||
rule keyword_while 'while' space? end
|
||||
|
||||
rule keyword_true
|
||||
('true' space?) { Ast::TrueExpression.new }
|
||||
end
|
||||
|
||||
# this rule is just to make sure identifiers can't be keywords. Kind of duplication here, but we need the
|
||||
# space in above rules, so just make sure to add any here too.
|
||||
rule keyword ('begin' | 'def' | 'do' | 'else' | 'end' |
|
||||
'false' | 'if' | 'rescue' | 'true' | 'nil' |
|
||||
'unless' | 'until' | 'while') space?
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue
Block a user