lib/basic101/parser.rb in basic101-0.1.0 vs lib/basic101/parser.rb in basic101-0.2.0
- old
+ new
@@ -1,457 +1,28 @@
-module Basic101
-
- class Parser < Parslet::Parser
-
- rule(:space) do
- match(' ').repeat(1)
- end
-
- rule(:new_line) do
- str("\r").maybe >> str("\n")
- end
-
- rule(:space?) do
- space.maybe
- end
-
- rule(:printable) do
- match('[[:print:]]')
- end
-
- rule(:decimal) do
- match('[0-9]').repeat(1)
- end
-
- rule(:sign) do
- match('[+-]')
- end
-
- rule(:integer) do
- (sign.maybe >> decimal).as(:integer)
- end
-
- rule(:fixed) do
- sign.maybe >>
- (decimal >> str('.') >> decimal.maybe) |
- (str('.') >> decimal)
- end
-
- rule(:exponent) do
- str('E') >> sign.maybe >> decimal
- end
-
- rule(:float) do
- (fixed >> exponent.maybe |
- sign.maybe >> decimal >> exponent).as(:float)
- end
-
- rule(:unquoted_string) do
- match('(?=[[:print:]])[^,": ]').repeat(0).as(:string)
- end
-
- rule(:quoted_string) do
- str('"') >>
- match('(?=[[:print:]])[^"]').repeat(0).maybe.as(:string) >>
- str('"')
- end
-
- rule(:user_defined_function_identifier) do
- (str('FN') >> base_identifier >>
- str('$').maybe).as(:function_identifier)
- end
-
- rule(:built_in_function_identifier) do
- (str('ABS') |
- str('ASC') |
- str('CHR$') |
- str('COS') |
- str('EXP') |
- str('INT') |
- str('LEFT$') |
- str('LEN') |
- str('LOG') |
- str('MID$') |
- str('RIGHT$') |
- str('RND') |
- str('SGN') |
- str('SIN') |
- str('SQR') |
- str('STR$') |
- str('TAB') |
- str('TAN') |
- str('VAL')).as(:function_identifier)
- end
-
- rule(:function_identifier) do
- user_defined_function_identifier |
- built_in_function_identifier
- end
-
- rule(:keyword) do
- str('AND') |
- str('DATA') |
- str('DEF') |
- str('DIM') |
- str('ELSE') |
- str('ELSE') |
- str('END') |
- str('FOR') |
- str('GOSUB') |
- str('GOTO') |
- str('GOTO') |
- str('IF') |
- str('INPUT') |
- str('LET') |
- str('NEXT') |
- str('NOT') |
- str('ON') |
- str('OR') |
- str('PRINT') |
- str('RANDOMIZE') |
- str('READ') |
- str('REM') |
- str('RESTORE') |
- str('RETURN') |
- str('STEP') |
- str('STOP') |
- str('THEN') |
- str('TO')
- end
-
- rule(:base_identifier) do
- (keyword.absent? >> match('[A-Z]')) >>
- (keyword.absent? >> match('[A-Z0-9]')).repeat(0)
- end
-
- rule(:numeric_identifier) do
- base_identifier.as(:numeric_identifier)
- end
-
- rule(:string_identifier) do
- (base_identifier >> str('$')).as(:string_identifier)
- end
-
- rule(:identifier) do
- string_identifier | numeric_identifier
- end
-
- rule(:argument_list) do
- expression >> (space? >> str(',') >> space? >> expression).repeat(0)
- end
-
- rule(:array_reference) do
- identifier.as(:subscript_base) >> space? >>
- str('(') >> space? >> argument_list.as(:argument_list) >>
- space? >> str(')')
- end
-
- rule(:scalar_reference) do
- identifier.as(:scalar_reference)
- end
-
- rule(:reference) do
- array_reference | scalar_reference
- end
-
- rule(:scalar_reference_list) do
- scalar_reference >>
- (space? >> str(',') >>
- space? >> scalar_reference).repeat(0)
- end
-
- rule(:reference_list) do
- reference >> (space? >> str(',') >> space? >> reference).repeat(0)
- end
-
- rule(:let_statement) do
- (str('LET') >> space?).maybe >>
- reference.as(:lvalue) >> space? >>
- str('=') >> space? >> expression.as(:rvalue)
- end
-
- rule(:multiply_op) do
- (str('*').as(:multiply) |
- str('/').as(:divide))
- end
-
- rule(:addition_op) do
- (str('+').as(:add) |
- str('-').as(:subtract))
- end
-
- rule(:comparison_op) do
- (str('=').as(:eq) |
- str('<>').as(:ne) |
- str('>=').as(:ge) |
- str('<=').as(:le)) |
- str('<').as(:lt) |
- str('>').as(:gt)
- end
-
- rule(:and_op) do
- str('AND').as(:and)
- end
-
- rule(:or_op) do
- str('OR').as(:or)
- end
-
- rule(:function_call) do
- function_identifier.as(:function_identifier) >> space? >>
- str('(') >> space? >> argument_list.as(:argument_list) >>
- space? >> str(')')
- end
-
- rule(:factor) do
- quoted_string |
- float |
- integer |
- function_call |
- reference |
- str('(') >> space? >> expression >> space? >> str(')')
- end
-
- rule(:power) do
- (factor.as(:left) >>
- space? >> str('^').as(:power) >>
- space? >> power.as(:right)) |
- factor
- end
-
- rule(:negation) do
- (str('-') >>
- space? >> power).as(:negation) |
- power
- end
-
- rule(:term) do
- negation.as(:left) >>
- (space? >> multiply_op.as(:operator) >>
- space? >> negation.as(:right)
- ).repeat(1).as(:operations).maybe
- end
-
- rule(:simple_expression) do
- term.as(:left) >>
- (space? >> addition_op.as(:operator) >>
- space? >> term.as(:right)
- ).repeat(1).as(:operations).maybe
- end
-
- rule(:comparison_expression) do
- simple_expression.as(:left) >>
- (space? >> comparison_op.as(:operator) >>
- space? >> simple_expression.as(:right)
- ).repeat(1).as(:operations).maybe
- end
-
- rule(:not_expression) do
- (str('NOT') >> space? >> comparison_expression).as(:not) |
- comparison_expression
- end
-
- rule(:and_expression) do
- not_expression.as(:left) >>
- (space? >> and_op.as(:operator) >>
- space? >> not_expression.as(:right)
- ).repeat(1).as(:operations).maybe
- end
-
- rule(:or_expression) do
- and_expression.as(:left) >>
- (space? >> or_op.as(:operator) >>
- space? >> and_expression.as(:right)
- ).repeat(1).as(:operations).maybe
- end
-
- rule(:expression) do
- or_expression
- end
-
- rule(:remark_statement) do
- (str('REM') >> printable.repeat(0)).as(:remark)
- end
-
- rule(:print_separator) do
- match('[;,]').as(:print_separator)
- end
-
- rule(:print_arguments) do
- (space? >> (expression | print_separator)).repeat(0)
- end
-
- rule(:print_separator) do
- match('[;,]').as(:print_separator)
- end
-
- rule(:print_statement) do
- str('PRINT').as(:print) >> print_arguments.as(:print_arguments)
- end
-
- rule(:goto_statement) do
- str('GOTO').as(:goto) >> space? >> integer
- end
-
- rule(:if_block) do
- (integer.as(:if_line_number) |
- statements)
- end
-
- rule(:if_statement) do
- str('IF').as(:if) >>
- space? >> expression.as(:condition) >>
- (space? >> str('THEN')).maybe >>
- space? >> if_block.as(:then_block) >>
- (space? >> str('ELSE') >> space? >> if_block).maybe.as(:else_block)
- end
-
- rule(:randomize_statement) do
- str('RANDOMIZE').as(:randomize)
- end
-
- rule(:prompt_delimeter) do
- str(';').as(:prompt_delimeter) |
- str(',').as(:null_prompt_delimeter)
- end
-
- rule(:input_statement) do
- str('INPUT').as(:input) >>
- (space? >> quoted_string.as(:prompt) >>
- space? >> prompt_delimeter.as(:prompt_delimeter)).maybe >>
- space? >> reference_list.as(:references)
- end
-
- rule(:end_statement) do
- str('END').as(:end)
- end
-
- rule(:dim_statement) do
- str('DIM').as(:dim) >>
- (space? >> array_reference >>
- (space? >> str(',') >>
- space? >> array_reference
- ).repeat(0)
- ).as(:references)
- end
-
- rule(:for_statement) do
- str('FOR') >>
- space? >> scalar_reference.as(:reference) >>
- space? >> str('=') >>
- space? >> expression.as(:from) >>
- space? >> str('TO') >>
- space? >> expression.as(:to) >>
- (space? >> str('STEP') >> space? >> expression).maybe.as(:step)
- end
-
- rule(:next_statement) do
- str('NEXT').as(:next) >>
- (space? >> reference >>
- (space? >> str(',') >>
- space? >> reference
- ).repeat(0)
- ).maybe.as(:references)
- end
-
- rule(:on_goto_statement) do
- str('ON').as(:on_goto) >>
- space? >>expression.as(:expression) >>
- space? >> str('GOTO') >>
- (
- space? >> integer >>
- (
- space? >> str(',') >>
- space? >> integer
- ).repeat(0)
- ).as(:line_numbers)
- end
-
- rule(:data_item) do
- float | integer | quoted_string | unquoted_string
- end
-
- rule(:data_statement) do
- str('DATA') >>
- (space? >> data_item >>
- (space? >> str(',') >>
- space? >> data_item
- ).repeat(0)
- ).as(:data_items)
- end
-
- rule(:read_statement) do
- str('READ').as(:read) >>
- space? >> reference_list.as(:references)
- end
-
- rule(:gosub_statement) do
- str('GOSUB').as(:gosub) >>
- space? >> integer.as(:line_number)
- end
-
- rule(:return_statement) do
- str('RETURN').as(:return)
- end
-
- rule(:stop_statement) do
- str('STOP').as(:stop)
- end
-
- rule(:restore_statement) do
- str('RESTORE').as(:restore) >>
- (space? >> integer).maybe.as(:line_number)
- end
-
- rule(:define_function_statement) do
- str('DEF').as(:def) >>
- space? >> user_defined_function_identifier.as(:identifier) >>
- (space? >> str('(') >>
- space? >> scalar_reference_list >>
- space? >> str(')')
- ).as(:parameters) >>
- space? >> str('=') >>
- space? >> expression.as(:expression)
- end
-
- rule(:statement) do
- (goto_statement |
- remark_statement |
- print_statement |
- if_statement |
- randomize_statement |
- input_statement |
- end_statement |
- dim_statement |
- for_statement |
- next_statement |
- on_goto_statement |
- data_statement |
- read_statement |
- gosub_statement |
- return_statement |
- stop_statement |
- restore_statement |
- define_function_statement |
- let_statement)
- end
-
- rule(:statements) do
- statement >>
- (space? >> str(':') >>
- space? >> statement).repeat(0) >>
- space? >> str(':').maybe
- end
-
- rule(:line) do
- (integer >> space? >> statements.as(:statements))
- end
-
- rule(:program) do
- ((line >> (new_line >> line).repeat(0) >> new_line.maybe).maybe).as(:program)
- end
-
- root(:program)
-
- end
-
-end
+require_relative 'parser/data_statement'
+require_relative 'parser/define_function_statement'
+require_relative 'parser/dim_statement'
+require_relative 'parser/end_statement'
+require_relative 'parser/expression'
+require_relative 'parser/for_statement'
+require_relative 'parser/function_call'
+require_relative 'parser/gosub_statement'
+require_relative 'parser/goto_statement'
+require_relative 'parser/identifier'
+require_relative 'parser/if_statement'
+require_relative 'parser/input_statement'
+require_relative 'parser/let_statement'
+require_relative 'parser/next_statement'
+require_relative 'parser/numeric'
+require_relative 'parser/on_goto_statement'
+require_relative 'parser/print_statement'
+require_relative 'parser/program'
+require_relative 'parser/randomize_statement'
+require_relative 'parser/read_statement'
+require_relative 'parser/reference'
+require_relative 'parser/remark_statement'
+require_relative 'parser/restore_statement'
+require_relative 'parser/return_statement'
+require_relative 'parser/space'
+require_relative 'parser/statements'
+require_relative 'parser/stop_statement'
+require_relative 'parser/string'